Compare commits

...

167 Commits

Author SHA1 Message Date
684dbcfd87 chore: 版本更新至 5.27.1 2023-06-16 17:06:45 +08:00
4f8b961e2c Merge branch 'hotfix/v5.27.0-890/GHZS-2719' into 'release'
fix: 首页顶部tab栏图片显示问题 https://jira.shanqu.cc/browse/GHZS-2719

See merge request halo/android/assistant-android!1134
2023-06-16 14:21:55 +08:00
58a7f7c3fa Merge branch 'hotfix/v5.27.0-890/crashes' into 'release'
fix: 捕抓获取是否已安装情况时的闪退...

See merge request halo/android/assistant-android!1135
2023-06-16 14:21:50 +08:00
ae8267d96d fix: 首页顶部tab栏图片显示问题 https://jira.shanqu.cc/browse/GHZS-2719 2023-06-16 14:18:33 +08:00
e20af462b7 fix: 捕抓获取是否已安装情况时的闪退 https://sentry.shanqu.cc/organizations/lightgame/issues/304548/?project=22&query=dist%3A890+level%3Afatal&statsPeriod=14d 2023-06-16 14:17:36 +08:00
e2773ed8c7 Merge branch 'feat/update_gdt_sdk' into 'release'
feat: 更新广点通 SDK

See merge request halo/android/assistant-android!1132
2023-06-16 11:33:19 +08:00
c77e5ca56b Merge branch 'pack/v5.25.3-853/change_kuaishou_channel_sdk' into 'release'
更新快手 SDK ,对接快手渠道 SDK,调整快手 APP ID https://jira.shanqu.cc/browse/GHZS-2306

See merge request halo/android/assistant-android!1131
2023-06-16 11:26:44 +08:00
e78c23ca4f Merge branch 'release' into 'pack/v5.25.3-853/change_kuaishou_channel_sdk'
# Conflicts:
#   app/src/kuaishou/java/com/gh/gamecenter/KuaishouHelper.kt
2023-06-16 03:26:17 +00:00
b790d71aa5 feat: 更新快手 SDK,更换默认帐号 2023-06-15 17:22:51 +08:00
5c91023a68 Merge branch 'hotfix/v5.27.0-890/wrong_time_issue' into 'release'
fix: 我的收藏-帖子时间显示问题 https://jira.shanqu.cc/browse/GHZS-2675

See merge request halo/android/assistant-android!1119
2023-06-14 14:40:35 +08:00
2eae71bc96 fix: 我的收藏-帖子时间显示问题 https://jira.shanqu.cc/browse/GHZS-2675 2023-06-14 14:33:54 +08:00
909477ec7f Merge branch 'hotfix/v5.27.0-890/vertical_slide_data_issue' into 'release'
fix: 游戏专题数据显示问题 https://jira.shanqu.cc/browse/GHZS-2665

See merge request halo/android/assistant-android!1116
2023-06-14 13:50:28 +08:00
a5da376f62 fix: 游戏专题数据显示问题 https://jira.shanqu.cc/browse/GHZS-2665 2023-06-14 11:54:38 +08:00
d084cb1c34 Merge branch 'fix/GHZS-2516' into 'release'
fix: 神策首次事件取值的相关排查(添加开发校验埋点) https://jira.shanqu.cc/browse/GHZS-2516

See merge request halo/android/assistant-android!1110
2023-06-12 15:17:41 +08:00
411bf3561f fix: 神策首次事件取值的相关排查(添加开发校验埋点) https://jira.shanqu.cc/browse/GHZS-2516 2023-06-12 15:11:58 +08:00
610c006aeb Merge branch 'fix/pad_display_issue' into 'dev'
fix: 低版本系统不支持新 API 导致获取不到软键盘高度的问题 https://jira.shanqu.cc/browse/GHZS-2639

See merge request halo/android/assistant-android!1107
2023-06-09 16:40:49 +08:00
ffa81bc4c1 fix: 低版本系统不支持新 API 导致获取不到软键盘高度的问题 https://jira.shanqu.cc/browse/GHZS-2639 2023-06-09 16:31:43 +08:00
67477ac20a feat: 更新广点通 SDK 2023-06-09 15:39:40 +08:00
a6a16e4694 Merge branch 'fix/GHZS-2651' into 'dev'
fix: 【光环助手】首页/版块内容列表-游戏单图片显示(0609测试) https://jira.shanqu.cc/browse/GHZS-2651

See merge request halo/android/assistant-android!1105
2023-06-09 13:51:56 +08:00
8f8352dc12 fix: 【光环助手】首页/版块内容列表-游戏单图片显示(0609测试) https://jira.shanqu.cc/browse/GHZS-2651 2023-06-09 13:49:06 +08:00
1bbbe575f2 Merge branch 'fix/oaid_crash' into 'dev'
ci: 移除 byteX 的 access_inline 插件

See merge request halo/android/assistant-android!1104
2023-06-09 10:08:53 +08:00
5975d9850f Merge branch 'fix/webview_multi_process_crash' into 'dev'
fix: 修复部分设备出现的多进程访问 WebView 数据闪退

See merge request halo/android/assistant-android!1103
2023-06-09 10:08:47 +08:00
ef001b0a77 ci: 移除 byteX 的 access_inline 插件 2023-06-09 09:58:04 +08:00
fd49ecbc8a fix: 修复部分设备出现的多进程访问 WebView 数据闪退 2023-06-08 17:25:33 +08:00
d683969eda Merge branch 'feat/CWZS-76' into 'dev'
feat: 下载弹窗卖点icon更换 https://jira.shanqu.cc/browse/CWZS-74

See merge request halo/android/assistant-android!1101
2023-06-08 16:07:13 +08:00
f8527da9df feat: 下载弹窗卖点icon更换 https://jira.shanqu.cc/browse/CWZS-74 2023-06-08 16:00:06 +08:00
f50d901171 Merge branch 'fix/GHZS-2639' into 'dev'
fix: 华为pad简易适配—0606测试 https://jira.shanqu.cc/browse/GHZS-2639

See merge request halo/android/assistant-android!1099
2023-06-08 14:54:01 +08:00
71db870bd2 Merge branch 'fix/GHZS-2651' into 'dev'
fix: 【光环助手】首页/版块内容列表-游戏单图片显示 https://jira.shanqu.cc/browse/GHZS-2651

See merge request halo/android/assistant-android!1098
2023-06-08 14:49:03 +08:00
b4c550f71b fix: 华为pad简易适配—0606测试 https://jira.shanqu.cc/browse/GHZS-2639 2023-06-08 14:43:14 +08:00
91bde61054 fix: 【光环助手】首页/版块内容列表-游戏单图片显示 https://jira.shanqu.cc/browse/GHZS-2651 2023-06-08 14:26:25 +08:00
d7940121ee Merge branch 'release' into 'dev'
Release

See merge request halo/android/assistant-android!1096
2023-06-08 09:19:32 +08:00
ef9c473301 Merge branch 'fix/gallery_slide_crash' into 'release'
fix: 修复滚动图集在游戏数量较少时的数组越界闪退

See merge request halo/android/assistant-android!1094
2023-06-07 16:24:18 +08:00
2c82437449 Merge branch 'fix/v2_test_crash' into 'release'
fix: 捕抓新游开测快速滑动时偶发的空指针异常

See merge request halo/android/assistant-android!1095
2023-06-07 16:24:04 +08:00
311e5e4225 fix: 捕抓新游开测快速滑动时偶发的空指针异常 2023-06-07 16:16:53 +08:00
91864e3681 fix: 修复滚动图集在游戏数量较少时的数组越界闪退 2023-06-07 16:07:31 +08:00
5e66db7435 Merge branch 'release' into 'dev'
Release

See merge request halo/android/assistant-android!1091
2023-06-07 11:51:04 +08:00
e7c74d3f39 Merge branch 'fix/GHZS-2643' into 'release'
fix: 神策埋点补充—0606测试 https://jira.shanqu.cc/browse/GHZS-2643

See merge request halo/android/assistant-android!1090
2023-06-07 10:43:55 +08:00
d0fa02b221 fix: 神策埋点补充—0606测试 https://jira.shanqu.cc/browse/GHZS-2643 2023-06-07 10:40:06 +08:00
70e4378ef0 feat: 推广打包接入快手分包sdk https://jira.shanqu.cc/browse/GHZS-2306 2023-06-07 09:28:12 +08:00
f8ee943678 Merge branch 'fix/typo' into 'release'
fix: 调整存档缺省文案

See merge request halo/android/assistant-android!1089
2023-06-06 17:51:43 +08:00
918aa17fbd fix: 调整存档缺省文案 2023-06-06 17:49:56 +08:00
0a7a3d9878 Merge branch 'fix/vgame' into 'release'
fix: 修复畅玩游戏功能没有开启的问题

See merge request halo/android/assistant-android!1088
2023-06-06 17:30:56 +08:00
b6a823e793 fix: 修复畅玩游戏功能没有开启的问题 2023-06-06 17:27:41 +08:00
9a95a4623d Merge branch 'release' into 'dev'
Release

See merge request halo/android/assistant-android!1086
2023-06-06 16:52:39 +08:00
206bc1bfcc Merge branch 'fix/CWZS-71' into 'release'
fix:【光环助手】5.27验收问题汇总(2) https://jira.shanqu.cc/browse/CWZS-71

See merge request halo/android/assistant-android!1085
2023-06-06 16:52:02 +08:00
4045e42a7b fix:【光环助手】5.27验收问题汇总(2) https://jira.shanqu.cc/browse/CWZS-71 2023-06-06 16:39:38 +08:00
15f283d330 Merge branch 'release' into 'dev'
合并5.26.0相关变更

See merge request halo/android/assistant-android!1083
2023-06-06 14:34:00 +08:00
97bafee09e Merge branch 'fix/gapps_install_issue' into 'release'
fix: 修复畅玩安装谷歌框架时应用切换到后台返回时安装卡住的问题

See merge request halo/android/assistant-android!1081
2023-06-06 14:29:45 +08:00
e32745d9d7 Merge branch 'fix/vspace_delete_issue' into 'release'
fix: 修复畅玩组件安装包被外部删除时再安装会一直触发安装空文件的问题

See merge request halo/android/assistant-android!1082
2023-06-06 14:29:41 +08:00
c37a54ac89 fix: 修复畅玩安装谷歌框架时应用切换到后台返回时安装卡住的问题 2023-06-06 14:27:11 +08:00
607d514ae9 fix: 修复畅玩组件安装包被外部删除时再安装会一直触发安装空文件的问题 2023-06-06 14:18:33 +08:00
62ee0b4a6e Merge branch 'feature/GHZS-2632' into 'release'
feat: 神策埋点补充—客户端 https://jira.shanqu.cc/browse/GHZS-2632

See merge request halo/android/assistant-android!1080
2023-06-06 11:31:00 +08:00
11ff054520 feat: 神策埋点补充—客户端 https://jira.shanqu.cc/browse/GHZS-2632 2023-06-06 10:37:43 +08:00
e96fc0f3b4 Merge branch 'fix/vgame_install_issue' into 'release'
fix: 修复畅玩游戏在安装时,手动再触发安装会出现安装失败的问题

See merge request halo/android/assistant-android!1079
2023-06-05 15:58:56 +08:00
a7875b21c9 fix: 修复畅玩游戏在安装时,手动再触发安装会出现安装失败的问题 2023-06-05 15:50:10 +08:00
e53154c810 Merge branch 'feat/GHZS-2596' into 'release'
feat: 游戏平台上报优化 https://jira.shanqu.cc/browse/GHZS-2596

See merge request halo/android/assistant-android!1078
2023-06-05 13:35:18 +08:00
e1d89725bc Merge branch 'fix/download_button_crash' into 'release'
fix: 修复DownloadButton偶发的闪退问题...

See merge request halo/android/assistant-android!1077
2023-06-05 11:31:59 +08:00
1d3ec9eff6 fix: 修复DownloadButton偶发的闪退问题... 2023-06-05 11:31:58 +08:00
0403743533 feat: 游戏平台上报优化 https://jira.shanqu.cc/browse/GHZS-2596 2023-06-05 11:17:06 +08:00
1f25b932d5 Merge branch 'fix/vspace_installed_error' into 'release'
fix: 增强检查应用是否已安装的方法

See merge request halo/android/assistant-android!1075
2023-06-02 15:42:02 +08:00
d3545bc766 fix: 增强检查应用是否已安装的方法 2023-06-02 15:27:36 +08:00
b2b858c403 Merge branch 'fix/vgame_uninstall_error' into 'release'
fix: 修复畅玩游戏安装情况判断异常的问题

See merge request halo/android/assistant-android!1074
2023-06-01 16:03:27 +08:00
debbe08262 fix: 修复畅玩游戏安装情况判断异常的问题 2023-06-01 15:58:35 +08:00
4e746a2b16 Merge branch 'fix/vgame_switch' into 'release'
fix: 修复覆盖安装时因为没有成功获取设置配置而导致功能被关闭的问题

See merge request halo/android/assistant-android!1073
2023-06-01 11:25:37 +08:00
b86e372e5b fix: 修复覆盖安装时因为没有成功获取设置配置而导致功能被关闭的问题 2023-06-01 11:16:42 +08:00
f65e76a94a Merge branch 'fix/CWZS-70' into 'release'
fix: 32位畅玩游戏下载流程埋点—0601测试 https://jira.shanqu.cc/browse/CWZS-70

See merge request halo/android/assistant-android!1072
2023-06-01 10:44:07 +08:00
05c8de827e fix: 32位畅玩游戏下载流程埋点—0601测试 https://jira.shanqu.cc/browse/CWZS-70 2023-06-01 10:39:18 +08:00
78eb10fa3c Merge branch 'feature/CWZS-66' into 'release'
feat: 32位组件-埋点补充-05/29 https://jira.shanqu.cc/browse/CWZS-66

See merge request halo/android/assistant-android!1071
2023-05-31 14:58:17 +08:00
23dfb7378b feat: 32位组件-埋点补充-05/29 https://jira.shanqu.cc/browse/CWZS-66 2023-05-31 14:39:13 +08:00
0e2e175194 Merge remote-tracking branch 'origin/dev' into dev-5.27.0 2023-05-31 11:37:32 +08:00
9050a04c3a Merge remote-tracking branch 'origin/release' into dev
# Conflicts:
#	dependencies.gradle
2023-05-31 11:29:19 +08:00
57df50b0a2 chore: 版本更新至 5.25.3 2023-05-31 11:08:46 +08:00
4ff21914c1 Merge branch 'fix/CWZS-69' into 'dev'
fix: 32位畅玩游戏下载流程—0530测试 https://jira.shanqu.cc/browse/CWZS-68

See merge request halo/android/assistant-android!1070
2023-05-31 09:45:50 +08:00
0dec30ff56 fix: 32位畅玩游戏下载流程—0530测试 https://jira.shanqu.cc/browse/CWZS-68 2023-05-31 09:09:23 +08:00
4bdfe6e190 Merge branch 'hotfix/v5.25.2-852/GHZS-2551' into 'release'
fix: 轮播图数据上报问题 https://jira.shanqu.cc/browse/GHZS-2551

See merge request halo/android/assistant-android!1069
2023-05-30 18:01:28 +08:00
55813cdaae fix: 轮播图数据上报问题 https://jira.shanqu.cc/browse/GHZS-2551 2023-05-30 17:54:55 +08:00
8668b2b4ec Merge branch 'feature-GHZS-2552' into 'dev-5.27.0'
feat:版主新增帖子置顶权限—0530测试 https://jira.shanqu.cc/browse/GHZS-2552

See merge request halo/android/assistant-android!1068
2023-05-30 16:20:12 +08:00
b758658ea6 feat:版主新增帖子置顶权限—0530测试 https://jira.shanqu.cc/browse/GHZS-2552 2023-05-30 16:20:12 +08:00
4ca9c32762 Merge branch 'feat/support_pad' into 'dev'
feat: 简单适配平板显示

See merge request halo/android/assistant-android!1067
2023-05-30 15:17:00 +08:00
af8fdd5d65 feat: 简单适配平板 2023-05-30 14:54:53 +08:00
36dd4f5a82 Merge branch 'fix/CWZS-65' into 'dev'
fix: 32位畅玩游戏下载流程—0529测试 https://jira.shanqu.cc/browse/CWZS-65

See merge request halo/android/assistant-android!1066
2023-05-30 14:42:00 +08:00
c7161e3483 fix: 32位畅玩游戏下载流程—0529测试 https://jira.shanqu.cc/browse/CWZS-65 2023-05-30 14:30:14 +08:00
bffaaffc56 Merge branch 'fix/remove_useless_request' into 'dev-5.27.0'
fix: 移除无用下载完成统计接口

See merge request halo/android/assistant-android!1065
2023-05-30 11:09:14 +08:00
3257dd4c53 Merge branch 'feat/GHZS-2406' into 'dev-5.27.0'
feat: 下载事件埋点补充 https://jira.shanqu.cc/browse/GHZS-2406

See merge request halo/android/assistant-android!1064
2023-05-30 11:09:02 +08:00
6793945606 feat: 下载事件埋点补充 https://jira.shanqu.cc/browse/GHZS-2406 2023-05-30 11:03:37 +08:00
52be14a4ef fix: 移除无用下载完成统计接口 2023-05-30 09:54:38 +08:00
e2cb5a31cf Merge branch 'fix/CWZS-64' into 'dev'
fix: 32位畅玩游戏下载流程—0529UI测试 https://jira.shanqu.cc/browse/CWZS-64

See merge request halo/android/assistant-android!1063
2023-05-29 18:04:04 +08:00
d807b7973b fix: 32位畅玩游戏下载流程—0529UI测试 https://jira.shanqu.cc/browse/CWZS-64 2023-05-29 18:01:57 +08:00
1fb0d13646 Merge branch 'feat/GHZS-2388' into 'dev'
feat: 广告位前置工作(接入新版 OAID SDK) https://jira.shanqu.cc/browse/GHZS-2389

See merge request halo/android/assistant-android!1062
2023-05-29 17:25:24 +08:00
68a3eadfeb feat: 广告位前置工作(接入新版 OAID SDK) https://jira.shanqu.cc/browse/GHZS-2389 2023-05-29 16:49:25 +08:00
a2d904c634 Merge branch 'feat/CWZS-58' into 'dev-5.27.0'
feat: 畅玩助手及游戏下载流程梳理 https://jira.shanqu.cc/browse/CWZS-58

See merge request halo/android/assistant-android!1061
2023-05-26 17:53:23 +08:00
56cd1bdad7 feat: 畅玩助手及游戏下载流程梳理 https://jira.shanqu.cc/browse/CWZS-58 2023-05-26 17:36:13 +08:00
999e1a3ad8 Merge branch 'hotfix/v5.25.2-852/GHZS-2409' into 'release'
fix: 神策后台下载相关事件转化率异常问题排查—客户端 https://jira.shanqu.cc/browse/GHZS-2409

See merge request halo/android/assistant-android!1060
2023-05-26 17:16:27 +08:00
8b4f71bc75 Merge remote-tracking branch 'origin/dev' into dev-5.27.0 2023-05-26 17:13:26 +08:00
be937703b8 fix: 神策后台下载相关事件转化率异常问题排查—客户端 https://jira.shanqu.cc/browse/GHZS-2409 2023-05-26 17:08:20 +08:00
aa069b7a21 Merge remote-tracking branch 'origin/release' into dev
# Conflicts:
#	dependencies.gradle
2023-05-26 16:59:59 +08:00
f89914746a Merge branch 'hotfix/v5.25.2-852/GHZS-2409' into 'release'
fix: 神策后台下载相关事件转化率异常问题排查—客户端 https://jira.shanqu.cc/browse/GHZS-2409

See merge request halo/android/assistant-android!1058
2023-05-26 16:42:47 +08:00
fb0db2feee Merge branch 'feature-GHZS-2428' into 'dev-5.27.0'
feat:版主新增帖子置顶权限—客户端 https://jira.shanqu.cc/browse/GHZS-2428

See merge request halo/android/assistant-android!1059
2023-05-26 16:36:10 +08:00
250dba9198 fix: 神策后台下载相关事件转化率异常问题排查—客户端 https://jira.shanqu.cc/browse/GHZS-2409 2023-05-26 16:32:41 +08:00
4c531b40b0 feat:版主新增帖子置顶权限—客户端 https://jira.shanqu.cc/browse/GHZS-2428 2023-05-26 16:25:08 +08:00
875a84b5ae Merge branch 'hotfix/v5.25.2-852/import_error' into 'release'
fix: 修复缺少import问题

See merge request halo/android/assistant-android!1057
2023-05-26 14:53:16 +08:00
77b9b731e2 fix: 修复缺少import问题 2023-05-26 14:51:12 +08:00
bd11481c2d Merge branch 'feat/GHZS-2450' into 'dev'
feat: H5链接游戏适配优化 https://jira.shanqu.cc/browse/GHZS-2450

See merge request halo/android/assistant-android!1055
2023-05-26 14:36:34 +08:00
a3f1b09da1 feat: H5链接游戏适配优化 https://jira.shanqu.cc/browse/GHZS-2450 2023-05-26 14:27:10 +08:00
1798dfb64d Merge branch 'fix/CWZS-62' into 'dev'
fix: 32位畅玩游戏下载流程

See merge request halo/android/assistant-android!1054
2023-05-26 14:11:35 +08:00
8e5814d389 fix: 32位畅玩游戏下载流程—0526UI测试 https://jira.shanqu.cc/browse/CWZS-63 2023-05-26 14:06:01 +08:00
14c01cf171 fix: 32位畅玩游戏下载流程—0525测试 https://jira.shanqu.cc/browse/CWZS-62 2023-05-26 14:06:01 +08:00
c800dac1ec Merge branch 'hotfix/v5.25.2-852/GHZS-2518' into 'release'
fix:【光环助手】右侧卡片曝光数据问题(0525测试1-2) https://jira.shanqu.cc/browse/GHZS-2518

See merge request halo/android/assistant-android!1053
2023-05-26 09:20:23 +08:00
88448b7b8d fix:【光环助手】右侧卡片曝光数据问题(0525测试1-2) https://jira.shanqu.cc/browse/GHZS-2518 2023-05-25 18:02:33 +08:00
77a1e5fea7 Merge branch 'fix/v5.25.2-852/update_install_error' into 'release'
fix: 修复游戏更新安装问题 https://jira.shanqu.cc/browse/GHZS-2517

See merge request halo/android/assistant-android!1052
2023-05-25 15:42:30 +08:00
ef0a212b85 fix: 修复游戏更新安装问题 https://jira.shanqu.cc/browse/GHZS-2517 2023-05-25 15:10:13 +08:00
2ee4ad6752 ci: 邮件编译添加 dev-5.27.0 2023-05-25 11:41:55 +08:00
9173a73ed0 Merge branch 'fix/v5.25.2-852/subject_display_error' into 'release'
fix: 修复横向多列专题的显示问题 https://jira.shanqu.cc/browse/GHZS-2522

See merge request halo/android/assistant-android!1051
2023-05-25 11:22:34 +08:00
5d8e208ef8 fix: 修复横向多列专题的显示问题 https://jira.shanqu.cc/browse/GHZS-2522 2023-05-25 11:10:50 +08:00
309111c422 Merge branch 'hotfix/v5.25.2-852/GHZS-2518' into 'release'
fix:【光环助手】右侧卡片曝光数据问题 https://jira.shanqu.cc/browse/GHZS-2518

See merge request halo/android/assistant-android!1050
2023-05-24 18:00:20 +08:00
3c3a228500 fix:【光环助手】右侧卡片曝光数据问题 https://jira.shanqu.cc/browse/GHZS-2518 2023-05-24 17:56:31 +08:00
33a5e2061f chore: 版本更新至 5.25.2 2023-05-24 16:56:34 +08:00
b62b1f399c Merge branch 'hotfix/v5.25.1-851/ad_error' into 'release'
fix: 修复开屏广告无响应的问题

See merge request halo/android/assistant-android!1049
2023-05-24 16:49:05 +08:00
c4449db90a fix: 修复开屏广告无响应的问题 2023-05-24 16:13:55 +08:00
6edd9f2204 Merge branch 'hotfix/v5.25.1-851/database_crash' into 'release'
fix: 修复数据库变更导致的畅玩数据转化闪退

See merge request halo/android/assistant-android!1048
2023-05-24 14:09:17 +08:00
8508b9ece2 fix: 修复数据库变更导致的畅玩数据转化闪退 2023-05-24 11:52:26 +08:00
20d5ef7a6e Merge branch 'hotfix/v5.25.1-851/GHZS-2518' into 'release'
fix: 【光环助手】右侧卡片曝光数据问题 https://jira.shanqu.cc/browse/GHZS-2518

See merge request halo/android/assistant-android!1047
2023-05-24 10:47:59 +08:00
ff70d7a48a fix: 【光环助手】右侧卡片曝光数据问题 https://jira.shanqu.cc/browse/GHZS-2518 2023-05-24 09:55:31 +08:00
4bc2374cb4 chore: 版本更新至 5.25.1 2023-05-23 15:50:38 +08:00
73d7a38886 Merge branch 'feature/GHZS-2448' into 'dev-5.27.0'
feat: 下载流量提示弹窗埋点补充—客户端 https://jira.shanqu.cc/browse/GHZS-2448

See merge request halo/android/assistant-android!1045
2023-05-23 15:28:09 +08:00
8efa858a01 Merge branch 'hotfix/v5.25.0-850/oaid_crash' into 'release'
fix: 修复oaid初始化sdk出现的闪退问题...

See merge request halo/android/assistant-android!1044
2023-05-23 15:28:00 +08:00
53e2297976 fix: 修复oaid初始化sdk出现的闪退问题... 2023-05-23 15:28:00 +08:00
9cd5e342ac Merge branch 'hotfix/v5.25.0-850/forum_video_crash' into 'release'
fix: 修复视频贴闪退问题...

See merge request halo/android/assistant-android!1046
2023-05-23 11:40:21 +08:00
26dfb79ece fix: 修复视频贴闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/298062/?project=22&query=dist%3A850&statsPeriod=14d 2023-05-23 11:12:22 +08:00
e1f70ce788 feat: 下载流量提示弹窗埋点补充—客户端 https://jira.shanqu.cc/browse/GHZS-2448 2023-05-22 17:52:19 +08:00
7bc36814b7 Merge branch 'hotfix/v5.25.0-850/geetest_crash' into 'release'
fix: 修复验证码校验闪退问题

See merge request halo/android/assistant-android!1043
2023-05-22 17:45:37 +08:00
b29651ecfb fix: 修复验证码校验闪退问题 2023-05-22 17:34:35 +08:00
fe5b93c35a chore: 版本更新至 5.27.0 2023-05-22 11:46:06 +08:00
74c3e7a10d Merge branch 'dev-5.26.0' into dev-5.27.0 2023-05-22 11:41:49 +08:00
deb2b07644 Merge remote-tracking branch 'origin/dev' into dev-5.26.0 2023-05-22 11:27:59 +08:00
c6b433d09c Merge branch 'feature-GHZS-2444' into 'dev-5.27.0'
feat:游戏礼包相关优化—客户端 https://jira.shanqu.cc/browse/GHZS-2444

See merge request halo/android/assistant-android!1039
2023-05-22 11:04:15 +08:00
c556a127f5 feat:游戏礼包相关优化—客户端 https://jira.shanqu.cc/browse/GHZS-2444 2023-05-22 11:00:43 +08:00
bdfd88a4c3 Merge branch 'fix/GHZS-2426' into 'dev-5.26.0'
fix: 已安装列表游戏显示问题 https://jira.shanqu.cc/browse/GHZS-2426

See merge request halo/android/assistant-android!1038
2023-05-19 15:42:25 +08:00
2697fd57b4 fix: 已安装列表游戏显示问题 https://jira.shanqu.cc/browse/GHZS-2426 2023-05-19 15:35:19 +08:00
06e238b2d5 Merge branch 'feature/CWZS-36' into 'dev-5.26.0'
feat: 32位畅玩游戏下载流程—客户端 https://jira.shanqu.cc/browse/CWZS-36

See merge request halo/android/assistant-android!1024
2023-05-18 17:59:29 +08:00
a4c323b5e0 feat: 32位畅玩游戏下载流程—客户端 https://jira.shanqu.cc/browse/CWZS-36 2023-05-18 17:59:28 +08:00
fdfb03348e Merge branch 'feature/GHZS-2408' into 'dev-5.26.0'
feat: 神策SDK升级—客户端 https://jira.shanqu.cc/browse/GHZS-2408

See merge request halo/android/assistant-android!1034
2023-05-18 16:46:10 +08:00
ba65c5e23a feat: 神策SDK升级—客户端 https://jira.shanqu.cc/browse/GHZS-2408 2023-05-18 15:06:21 +08:00
0f2fcdba68 Merge branch 'feature-delete-comment-dialog-title-center-gravity' into 'dev-5.26.0'
feat:评论详情删除评论弹窗标题居中

See merge request halo/android/assistant-android!1025
2023-05-11 17:04:15 +08:00
548156c159 feat:评论详情删除评论弹窗标题居中 2023-05-11 17:01:59 +08:00
ea08a52750 Merge branch 'feature-comment-delete-hint-center-gravity' into 'dev-5.26.0'
feat:评论详情删除评论弹窗内容居中

See merge request halo/android/assistant-android!1023
2023-05-11 15:49:05 +08:00
4c51ca7670 feat:评论详情删除评论弹窗内容居中 2023-05-11 15:43:52 +08:00
d1277aa1aa Merge branch 'feature-CWZS-50' into 'dev-5.26.0'
feat:云存档最新Tab排序逻辑调整—0510测试-客户端 https://jira.shanqu.cc/browse/CWZS-50

See merge request halo/android/assistant-android!1020
2023-05-11 10:12:11 +08:00
2381550e08 feat:云存档最新Tab排序逻辑调整—0510测试-客户端 https://jira.shanqu.cc/browse/CWZS-50 2023-05-11 10:04:54 +08:00
e57017f5f2 Merge branch 'feature-GHZS-2308' into 'dev-5.26.0'
feat: 文章增加评论删除功能—客户端 https://jira.shanqu.cc/browse/GHZS-2308

See merge request halo/android/assistant-android!1016
2023-05-09 17:26:29 +08:00
6506a18d6f feat: 文章增加评论删除功能—客户端 https://jira.shanqu.cc/browse/GHZS-2308 2023-05-09 17:26:29 +08:00
ed79b230aa Merge branch 'feature-CW-35' into 'dev-5.26.0'
feat: 畅玩助手问题反馈入口—客户端 https://jira.shanqu.cc/browse/CWZS-35

See merge request halo/android/assistant-android!1015
2023-05-09 16:41:51 +08:00
ac56650ce5 feat: 畅玩助手问题反馈入口—客户端 https://jira.shanqu.cc/browse/CWZS-35 2023-05-09 16:41:51 +08:00
0e988b2b49 Merge branch 'dev' into 'dev-5.26.0'
合并 5.24 & 5.25 变更

See merge request halo/android/assistant-android!1010
2023-05-08 10:40:28 +08:00
1b3c2da6d3 Merge branch 'feature/GHZS-2306' into 'dev-5.26.0'
feat: 推广打包接入快手分包sdk https://jira.shanqu.cc/browse/GHZS-2306

See merge request halo/android/assistant-android!1008
2023-05-06 16:56:06 +08:00
48209b05e7 feat: 推广打包接入快手分包sdk https://jira.shanqu.cc/browse/GHZS-2306 2023-05-06 16:52:02 +08:00
2da42d48e6 Merge branch 'feature/GHZS-2083' into 'dev-5.26.0'
feat: 推广打包增加配置信息及快速打包功能 https://jira.shanqu.cc/browse/GHZS-2082

See merge request halo/android/assistant-android!1007
2023-05-06 16:28:19 +08:00
f6b1813e88 feat: 推广打包增加配置信息及快速打包功能 https://jira.shanqu.cc/browse/GHZS-2082 2023-05-06 16:19:57 +08:00
9abd0de3fe Merge branch 'feature/CWZS-33' into 'dev-5.26.0'
feat: 下载完成提示条展示时机优化——客户端 https://jira.shanqu.cc/browse/CWZS-33

See merge request halo/android/assistant-android!1004
2023-05-05 16:45:33 +08:00
25cb0de6c0 feat: 下载完成提示条展示时机优化——客户端 https://jira.shanqu.cc/browse/CWZS-33 2023-05-05 16:33:57 +08:00
4db1147c4f Merge branch 'feature/GHZS-2285' into 'dev-5.26.0'
feat: 论坛详情页帖子列表展示优化—客户端 https://jira.shanqu.cc/browse/GHZS-2285

See merge request halo/android/assistant-android!1002
2023-05-05 11:40:10 +08:00
7802082797 feat: 论坛详情页帖子列表展示优化—客户端 https://jira.shanqu.cc/browse/GHZS-2285 2023-05-05 11:34:35 +08:00
81400a37f1 Merge branch 'feature/GHZS-2041' into 'dev-5.26.0'
feat: 光环助手支持神策测试环境与正式环境切换 https://jira.shanqu.cc/browse/GHZS-2041

See merge request halo/android/assistant-android!997
2023-04-28 10:37:07 +08:00
228a786f6c feat: 光环助手支持神策测试环境与正式环境切换 https://jira.shanqu.cc/browse/GHZS-2041 2023-04-28 10:32:36 +08:00
690c2e53d9 ci: CI 自动编译添加 5.26.0 2023-04-27 10:15:12 +08:00
5a72c12233 chore: 版本更改为 5.26.0 2023-04-27 10:15:12 +08:00
74f41404ef Merge branch 'dev-5.25.0' into 'dev-5.26.0'
合并 5.24.0 & 5.25.0 相关变更

See merge request halo/android/assistant-android!992
2023-04-27 09:57:27 +08:00
193 changed files with 3888 additions and 864 deletions

View File

@ -71,7 +71,8 @@ android_build:
exit_codes: 137
only:
- dev
- dev-5.25.0
- dev-5.26.0
- dev-5.27.0
# 代码检查
sonarqube_analysis:
@ -102,7 +103,8 @@ sonarqube_analysis:
exit_codes: 137
only:
- dev
- dev-5.25.0
- dev-5.26.0
- dev-5.27.0
## 发送简易检测结果报告
send_sonar_report:
@ -120,7 +122,8 @@ send_sonar_report:
exit_codes: 137
only:
- dev
- dev-5.25.0
- dev-5.26.0
- dev-5.27.0
oss-upload&send-email:
tags:
@ -152,4 +155,5 @@ oss-upload&send-email:
- /usr/local/bin/python /ci-android-mail.py
only:
- dev
- dev-5.25.0
- dev-5.26.0
- dev-5.27.0

View File

@ -163,7 +163,7 @@ android {
}
productFlavors {
// internal test dev host
// internal 内部测试包使用的 flavor接口包含包括测试和正式环境
internal {
dimension "env"
versionNameSuffix "-debug"
@ -175,7 +175,7 @@ android {
buildConfigField "String", "QUICK_LOGIN_APPKEY", "\"${DEV_QUICK_LOGIN_APPKEY}\""
}
// publish release host
// publish 发布时候使用的 flavor接口仅包含正式环境
publish {
dimension "env"
@ -201,11 +201,17 @@ android {
kuaishou {
dimension "env"
String KUAI_SHOU_APP_ID = ""
String KUAI_SHOU_APP_NAME = ""
buildConfigField "String", "DEV_API_HOST", "\"${API_HOST}\""
buildConfigField "String", "NEW_DEV_API_HOST", "\"${NEW_API_HOST}\""
buildConfigField "String", "DEV_VAPI_HOST", "\"${VAPI_HOST}\""
buildConfigField "String", "QUICK_LOGIN_APPID", "\"${QUICK_LOGIN_APPID}\""
buildConfigField "String", "QUICK_LOGIN_APPKEY", "\"${QUICK_LOGIN_APPKEY}\""
buildConfigField "String", "KUAI_SHOU_APP_ID", "\"${KUAI_SHOU_APP_ID}\""
buildConfigField "String", "KUAI_SHOU_APP_NAME", "\"${KUAI_SHOU_APP_NAME}\""
}
gdt {
@ -325,6 +331,7 @@ dependencies {
}
// implementation(project(':feature:vpn'))
implementation(project(':feature:pkg'))
implementation(project(':feature:oaid'))
implementation(project(':feature:floating-window'))
implementation(project(':feature:beizi_startup_ad'))
}

Binary file not shown.

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="utf-8"?>
<network-security-config>
<base-config>
<base-config cleartextTrafficPermitted="true">
<trust-anchors>
<!-- Trust user added CAs while debuggable only -->
<certificates src="user" />

View File

@ -5,15 +5,15 @@ import com.kwai.monitor.log.TurboAgent
import com.kwai.monitor.log.TurboConfig
object KuaishouHelper {
private const val APP_ID = "80655"
private const val APP_NAME = "guanghuanzhushou_1"
private val mAppId by lazy { BuildConfig.KUAI_SHOU_APP_ID.ifEmpty { "81537" } }
private val mAppName by lazy { BuildConfig.KUAI_SHOU_APP_NAME.ifEmpty { "guanghuanzhushou_1" } }
@JvmStatic
fun init(context: Context, channel: String) {
TurboAgent.init(
TurboConfig.TurboConfigBuilder.create(context)
.setAppId(APP_ID)
.setAppName(APP_NAME)
.setAppId(mAppId)
.setAppName(mAppName)
.setAppChannel(channel)
.build()
)

View File

@ -8,7 +8,7 @@ import com.gh.gamecenter.core.provider.IFlavorProvider
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.core.utils.TimeUtils
import com.halo.assistant.HaloApp
import com.leon.channel.helper.ChannelReaderUtil
import com.kwai.monitor.payload.TurboHelper
class FlavorProviderImp : IFlavorProvider {
@ -31,7 +31,7 @@ class FlavorProviderImp : IFlavorProvider {
}
override fun getChannelStr(application: Application): String {
var channel = ChannelReaderUtil.getChannel(application)
var channel = TurboHelper.getChannel(application)
if (channel == null || TextUtils.isEmpty(channel.trim())) {
channel = KUAISHOU_CHANNEL
}

Binary file not shown.

Binary file not shown.

View File

@ -112,6 +112,10 @@
tools:replace="android:name,android:allowBackup"
tools:targetApi="n">
<meta-data
android:name="EasyGoClient"
android:value="true" />
<meta-data
android:name="io.sentry.auto-init"
android:value="false" />

View File

@ -0,0 +1,27 @@
{
"easyGoVersion": "1.0",
"client": "com.gh.gamecenter",
"logicEntities": [
{
"head": {
"function": "magicwindow",
"required": "true"
},
"body": {
"mode":"1",
"activityPairs":[
{"from":"com.gh.gamecenter.MainActivity","to":"*"}
],
"defaultDualActivities": {
"mainPages": "com.gh.gamecenter.MainActivity"
},
"UX": {
"supportRotationUxCompat": "false",
"isDraggable": "true"
},
"transActivities":[
]
}
}
]
}

View File

@ -209,7 +209,7 @@ class DefaultJsApi(
runOnUiThread {
// 若畅玩列表中安装了,优先启动畅玩游戏
if (VHelper.isInstalled(packageName)) {
if (!VHelper.showDialogIfVSpaceIsNeeded(context, "", "")) {
if (!VHelper.showDialogIfVSpaceIsNeeded(context, "", "", "", "")) {
VHelper.launch(context, packageName)
}
} else {

View File

@ -9,7 +9,7 @@ class CheckDownloadHandler : ChainHandler() {
override fun handleRequest(context: Context, gameEntity: GameEntity) {
val apk = gameEntity.getApk().safelyGetInRelease(0) ?: return
DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean ->
DialogUtils.checkDownload(context, apk.size, gameEntity.id, gameEntity.name) { isSubscribe: Boolean ->
if (hasNext()) {
getNext()?.handleRequest(context, gameEntity)
} else {

View File

@ -122,17 +122,6 @@ public class Config {
return false;
}
/**
* 是否启用畅玩游戏
*/
public static boolean isVGameEnabled() {
if (getSettings() == null) {
return false;
}
return !"off".equals(getSettings().getGameSmooth());
}
/**
* VPN 开关选项是否开启
*/
@ -229,6 +218,8 @@ public class Config {
if (!TextUtils.isEmpty(json)) {
mSettingsEntity = GsonUtils.fromJson(json, SettingsEntity.class);
}
mSettingsEntity.setGameSmooth("off");
} catch (Exception e) {
e.printStackTrace();
}

View File

@ -24,6 +24,7 @@ import com.gh.common.chain.CertificationHandler;
import com.gh.common.chain.ChainBuilder;
import com.gh.common.chain.ChainHandler;
import com.gh.common.chain.CheckDownloadHandler;
import com.gh.common.chain.CheckStoragePermissionHandler;
import com.gh.common.chain.DownloadDialogHelperHandler;
import com.gh.common.chain.GamePermissionHandler;
import com.gh.common.chain.OverseaDownloadHandler;
@ -397,8 +398,9 @@ public class BindingAdapters {
}
ChainBuilder builder = new ChainBuilder();
builder.addHandler(new ValidateVSpaceHandler());
builder.addHandler(new GamePermissionHandler());
builder.addHandler(new CheckStoragePermissionHandler());
builder.addHandler(new ValidateVSpaceHandler());
builder.addHandler(new BrowserInstallHandler());
builder.addHandler(new PackageCheckHandler());
builder.addHandler(new DownloadDialogHelperHandler());

View File

@ -79,7 +79,7 @@ object ExposureManager {
private fun uploadExposures(eventSet: HashSet<ExposureEvent>, forced: Boolean) {
eventSet.forEach {
LoghubHelper.uploadLog(buildLog(it), LOG_STORE, forced)
it.recycle()
// it.recycle()
}
}

View File

@ -3,6 +3,7 @@ package com.gh.common.exposure
import android.text.TextUtils
import com.g00fy2.versioncompare.Version
import com.gh.common.util.PackageUtils
import com.gh.common.util.RealNameHelper
import com.gh.gamecenter.common.utils.FixedSizeLinkedHashSet
import com.gh.gamecenter.common.utils.toObject
import com.gh.gamecenter.feature.entity.ApkEntity
@ -42,7 +43,9 @@ object ExposureUtils {
source = traceEvent?.source ?: ArrayList(),
eTrace = ExposureTraceUtils.appendTrace(traceEvent),
event = ExposureType.DOWNLOAD
)
).apply {
this.payload.certification = RealNameHelper.getCertificationStatus()
}
if (!TextUtils.isEmpty(entity.id)) {
ExposureManager.log(exposureEvent)
}
@ -78,7 +81,9 @@ object ExposureUtils {
source = traceEvent?.source ?: ArrayList(),
eTrace = ExposureTraceUtils.appendTrace(traceEvent),
event = ExposureType.DOWNLOAD_COMPLETE
)
).apply {
this.payload.certification = RealNameHelper.getCertificationStatus()
}
exposureEvent.payload.host = host
exposureEvent.payload.path = path
exposureEvent.payload.speed = speed

View File

@ -49,7 +49,7 @@ object ArchiveDownloadButtonHelper {
downloadBtn.setOnClickListener {
when {
// 检查是否已安装畅玩助手
!VHelper.isVSpaceInstalled(context) -> showVspaceTipDialog(context, gameEntity)
!VHelper.isVSpaceInstalled(context) -> showVSpaceTipDialog(context, gameEntity)
// 检查是否已安装游戏
!VHelper.isInstalled(packageName) -> {
// 检查游戏是否在安装中
@ -82,7 +82,7 @@ object ArchiveDownloadButtonHelper {
}
}
private fun showVspaceTipDialog(context: Context, gameEntity: GameEntity?) {
private fun showVSpaceTipDialog(context: Context, gameEntity: GameEntity?) {
NewFlatLogUtils.logCloudArchiveVSpaceDownloadDialogShow()
DialogHelper.showDialog(
context,
@ -92,7 +92,7 @@ object ArchiveDownloadButtonHelper {
R.string.cancel.toResString(),
{
NewFlatLogUtils.logCloudArchiveVSpaceDownloadDialogClick(R.string.archive_vspace_dialog_confirm.toResString())
VHelper.showVspaceDialog(context, gameEntity)
VHelper.showVSpaceDialog(context, gameEntity)
},
{
NewFlatLogUtils.logCloudArchiveVSpaceDownloadDialogClick(R.string.cancel.toResString())

View File

@ -3,11 +3,15 @@ package com.gh.common.util;
import android.annotation.SuppressLint;
import android.app.Dialog;
import android.content.Context;
import android.graphics.drawable.ColorDrawable;
import android.text.TextUtils;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.PopupWindow;
import android.widget.TextView;
import androidx.annotation.Nullable;
@ -19,6 +23,7 @@ import com.gh.gamecenter.adapter.viewholder.CommentViewHolder;
import com.gh.gamecenter.common.callback.SimpleCallback;
import com.gh.gamecenter.common.retrofit.BiResponse;
import com.gh.gamecenter.common.retrofit.Response;
import com.gh.gamecenter.common.utils.DialogHelper;
import com.gh.gamecenter.common.utils.ExtensionsKt;
import com.gh.gamecenter.common.utils.ImageUtils;
import com.gh.gamecenter.core.utils.DisplayUtils;
@ -45,6 +50,7 @@ import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.Objects;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
@ -102,17 +108,27 @@ public class CommentUtils {
}
}
public static void showReportDialog(final CommentEntity commentEntity,
final Context context,
final boolean showConversation,
final String patch) {
final Dialog dialog = new Dialog(context);
LinearLayout container = new LinearLayout(context);
container.setOrientation(LinearLayout.VERTICAL);
container.setBackgroundColor(ContextCompat.getColor(context, R.color.background_white));
container.setPadding(0, DisplayUtils.dip2px(context, 12), 0, DisplayUtils.dip2px(context, 12));
public static void showMorePopupWindow(
final View anchor,
final CommentEntity commentEntity,
final boolean showConversation,
final String patch,
final OnCommentDeleteListener onCommentDeleteListener
) {
Context context = anchor.getContext();
LayoutInflater inflater = LayoutInflater.from(context);
View contentView = inflater.inflate(R.layout.layout_popup_container, null);
PopupWindow popupWindow = new PopupWindow(
contentView,
ViewGroup.LayoutParams.WRAP_CONTENT,
ViewGroup.LayoutParams.WRAP_CONTENT
);
popupWindow.setBackgroundDrawable(new ColorDrawable(0));
popupWindow.setTouchable(true);
popupWindow.setFocusable(true);
popupWindow.setOutsideTouchable(true);
LinearLayout container = contentView.findViewById(R.id.container);
List<String> dialogType = new ArrayList<>();
dialogType.add("复制");
dialogType.add("投诉");
@ -121,21 +137,23 @@ public class CommentUtils {
dialogType.add("查看对话");
}
String commentUserId = commentEntity.getUser().getId();
String userId = UserManager.getInstance().getUserId();
MeEntity me = commentEntity.getMe();
boolean isCommentedByUser = Objects.equals(commentUserId, userId);
boolean isContentAuthorOrModerator = me != null && (me.isModerator() || me.isContentAuthor());
if (isCommentedByUser || isContentAuthorOrModerator) {
dialogType.add("删除");
}
for (String s : dialogType) {
final TextView reportTv = new TextView(context);
View itemView = inflater.inflate(R.layout.layout_popup_option_item, container, false);
TextView reportTv = itemView.findViewById(R.id.hint_text);
reportTv.setText(s);
reportTv.setTextSize(17);
reportTv.setTextColor(ContextCompat.getColor(context, R.color.title));
reportTv.setBackgroundResource(R.drawable.textview_white_style);
int widthPixels = context.getResources().getDisplayMetrics().widthPixels;
reportTv.setLayoutParams(new LinearLayout.LayoutParams((widthPixels * 9) / 10,
LinearLayout.LayoutParams.WRAP_CONTENT));
reportTv.setPadding(DisplayUtils.dip2px(context, 20), DisplayUtils.dip2px(context, 12),
0, DisplayUtils.dip2px(context, 12));
container.addView(reportTv);
container.addView(itemView);
reportTv.setOnClickListener(v -> {
dialog.cancel();
popupWindow.dismiss();
switch (reportTv.getText().toString()) {
case "复制":
copyText(commentEntity.getContent(), context);
@ -143,19 +161,30 @@ public class CommentUtils {
case "投诉":
CheckLoginUtils.checkLogin(context, patch + "-投诉",
() -> showReportTypeDialog(commentEntity, context));
break;
case "查看对话":
context.startActivity(CommentDetailActivity.getIntent(context, commentEntity.getId(), null));
break;
case "删除":
DialogHelper.INSTANCE.showDialog(
context,
"提示",
"删除评论后,评论下所有的回复都将被删除",
"删除",
"取消",
() -> {
deleteComment(context, commentEntity, onCommentDeleteListener);
return null;
},
null,
new DialogHelper.Config("", false, true, true, false, -1)
);
break;
}
});
}
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(container);
dialog.show();
ExtensionsKt.showAutoOrientation(popupWindow, anchor, 0, 0);
}
private static void showReportTypeDialog(final CommentEntity commentEntity, final Context context) {
@ -430,6 +459,28 @@ public class CommentUtils {
});
}
public static void deleteComment(
final Context context,
final CommentEntity commentEntity,
final OnCommentDeleteListener listener
) {
Dialog dialog = DialogUtils.showWaitDialog(
context,
context.getString(R.string.post_dialog_hint)
);
RetrofitManager.getInstance().getApi()
.deleteComment(commentEntity.getId())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.doFinally(dialog::cancel)
.subscribe(new Response<ResponseBody>() {
@Override
public void onResponse(@Nullable ResponseBody response) {
listener.onCommentDelete();
}
});
}
// 设置评论item 用户相关的view(点赞/头像/用户名)
public static void setCommentUserView(Context mContext, CommentViewHolder holder, CommentEntity entity) {
@ -540,4 +591,8 @@ public class CommentUtils {
public interface OnVoteListener {
void onVote();
}
public interface OnCommentDeleteListener {
void onCommentDelete();
}
}

View File

@ -171,14 +171,25 @@ public class DataUtils {
IdCardEntity idCardEntity = data.getIdCard();
if (idCardEntity != null) {
values.put(GhContentProvider.KEY_IS_CERTIFICATED, !TextUtils.isEmpty(data.getIdCard().getId())); // 是否认证
values.put(GhContentProvider.KEY_IS_ADULT,
data.getIdCard().getMinor() == null
|| !data.getIdCard().getMinor()
);
boolean isCertificated = !TextUtils.isEmpty(data.getIdCard().getId());
boolean isAdult = data.getIdCard().getMinor() == null || !data.getIdCard().getMinor();
values.put(GhContentProvider.KEY_IS_CERTIFICATED, isCertificated); // 是否认证
values.put(GhContentProvider.KEY_IS_ADULT, isAdult); // 是否成年
if (!isCertificated) {
RealNameHelper.updateCertificationStatus(0);
} else {
if (isAdult) {
RealNameHelper.updateCertificationStatus(2);
} else {
RealNameHelper.updateCertificationStatus(1);
}
}
} else {
values.put(GhContentProvider.KEY_IS_CERTIFICATED, false);
values.put(GhContentProvider.KEY_IS_ADULT, false);
RealNameHelper.updateCertificationStatus(0);
}
EventBus.getDefault().post(new EBReuse(Constants.EB_REALNAME_RESULT));

View File

@ -121,7 +121,7 @@ public class DialogUtils {
return dialog;
}
public static void checkDownload(Context context, String size, CheckDownloadCallBack callBack) {
public static void checkDownload(Context context, String size, String gameId, String gameName, CheckDownloadCallBack callBack) {
if (!NetworkUtils.isNetworkConnected(context)) {
showNoConnectionDownloadDialog(context, () -> {
},
@ -136,7 +136,9 @@ public class DialogUtils {
// MtaHelper.onEvent("移动网络下载", NetworkUtils.getMobileNetworkType(context), "出现弹窗提示");
showDownloadDialog(context,
() -> callBack.onResponse(false),
() -> callBack.onResponse(true));
() -> callBack.onResponse(true),
gameId,
gameName);
}
}
@ -165,9 +167,11 @@ public class DialogUtils {
DialogHelper.showDialog(context, "下载提示", "网络异常,请检查手机网络状态", "知道了", "WiFi自动下载", listener::onConfirm, cancelListener::onCancel, false, "", "");
}
public static void showDownloadDialog(Context context, ConfirmListener listener, CancelListener cancelListener) {
public static void showDownloadDialog(Context context, ConfirmListener listener, CancelListener cancelListener, String gameId, String gameName) {
context = checkDialogContext(context);
NewFlatLogUtils.logDownloadMobileDataDialogShow(gameId, gameName);
final Dialog dialog = new Dialog(context, R.style.GhAlertDialog);
View contentView = LayoutInflater.from(context).inflate(R.layout.dialog_download_traffic, null);
@ -177,6 +181,7 @@ public class DialogUtils {
Context finalContext = context;
allowOnce.setOnClickListener(v -> {
NewFlatLogUtils.logDownloadMobileDataDialogClick(gameId, gameName, "允许一次");
AppExecutor.getUiExecutor().executeWithDelay(() -> {
Utils.toast(finalContext, "已使用移动网络下载,请注意流量消耗");
}, 500);
@ -185,11 +190,13 @@ public class DialogUtils {
// MtaHelper.onEvent("移动网络下载", NetworkUtils.getMobileNetworkType(finalContext), "本次允许");
});
wifiAuto.setOnClickListener(v -> {
NewFlatLogUtils.logDownloadMobileDataDialogClick(gameId, gameName, "WiFi自动下载");
cancelListener.onCancel();
dialog.dismiss();
// MtaHelper.onEvent("移动网络下载", NetworkUtils.getMobileNetworkType(finalContext), "连上WiFi后自动下载");
});
allowAlways.setOnClickListener(v -> {
NewFlatLogUtils.logDownloadMobileDataDialogClick(gameId, gameName, "总是允许");
SPUtils.setBoolean(getTrafficDownloadHintKey(), false);
AppExecutor.getUiExecutor().executeWithDelay(() -> {
// 显示了弹窗以后,即便下面这个 toast 放在 listener.onConfirm 后调用也是显示 listener.onConfirm 里的 toast
@ -201,6 +208,8 @@ public class DialogUtils {
// MtaHelper.onEvent("移动网络下载", NetworkUtils.getMobileNetworkType(finalContext), "总是允许");
});
dialog.setOnCancelListener(downloadDialog -> NewFlatLogUtils.logDownloadMobileDataDialogClick(gameId, gameName, "关闭弹窗"));
dialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
dialog.setContentView(contentView);
dialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));

View File

@ -311,13 +311,14 @@ object DirectUtils {
name = linkEntity.name,
display = linkEntity.display ?: Display()
),
entrance
entrance,
exposureEvent
)
}
"column_collection", "专题合集" -> directToColumnCollection(context, linkEntity.link!!, -1, entrance)
"server", "game_server", "开服表" -> directToGameServers(context, entrance, path)
"server", "game_server", "开服表" -> directToGameServers(context, entrance, path, exposureEvent)
"top_game_comment" -> directToAmway(context, null, entrance, path)
@ -439,11 +440,28 @@ object DirectUtils {
"game_list" -> directToGameCollectionSquare(context, entrance, "", "", "")
"game_list_detail" -> directToGameCollectionDetail(context, linkEntity.link ?: "", entrance)
"game_list_detail" -> directToGameCollectionDetail(
context,
linkEntity.link ?: "",
entrance,
exposureEvent = exposureEvent
)
"explore_column", "game_explore" -> context.startActivity(DiscoveryActivity.getIntent(context, entrance))
"explore_column", "game_explore" -> context.startActivity(
DiscoveryActivity.getIntent(
context,
entrance,
exposureEvent
)
)
"column_test_v2" -> context.startActivity(GameServerTestV2Activity.getIntent(context, entrance))
"column_test_v2" -> context.startActivity(
GameServerTestV2Activity.getIntent(
context,
entrance,
exposureEvent
)
)
"" -> {
// do nothing
@ -782,8 +800,11 @@ object DirectUtils {
jumpActivity(context, bundle)
}
/**
* 畅玩助手反馈跳转
*/
@JvmStatic
fun directToFeedbackCompat(
fun directToVGameFeedback(
context: Context,
content: String? = null,
hintType: String? = null,
@ -798,14 +819,14 @@ object DirectUtils {
if (isQaFeedback) {
bundle.putBoolean(KEY_IS_QA_FEEDBACK, true)
bundle.putString(KEY_QA_CONTENT_ID, qaContentId)
bundle.putSerializable(KEY_SUGGESTTYPE, SuggestType.normal)
bundle.putSerializable(KEY_SUGGESTTYPE, SuggestType.cwzsQuestion)
} else {
bundle.putString(KEY_CONTENT, content)
if (TextUtils.isEmpty(hintType)) {
bundle.putSerializable(KEY_SUGGESTTYPE, SuggestType.gameQuestion)
bundle.putString(KEY_SUGGEST_HINT_TYPE, KEY_PLUGIN)
} else {
bundle.putSerializable(KEY_SUGGESTTYPE, SuggestType.normal)
bundle.putSerializable(KEY_SUGGESTTYPE, SuggestType.cwzsQuestion)
bundle.putString(KEY_SUGGEST_HINT_TYPE, hintType)
}
}
@ -1353,11 +1374,17 @@ object DirectUtils {
* 跳转到板块
*/
@JvmStatic
fun directToBlock(context: Context, blockData: SubjectRecommendEntity, entrance: String) {
fun directToBlock(
context: Context,
blockData: SubjectRecommendEntity,
entrance: String,
exposureEvent: ExposureEvent? = null
) {
val bundle = Bundle()
bundle.putString(KEY_TO, BlockActivity::class.java.name)
bundle.putParcelable(KEY_BLOCK_DATA, blockData)
bundle.putString(KEY_ENTRANCE, entrance)
exposureEvent?.let { bundle.putParcelableArrayList(KEY_EXPOSURE_SOURCE_LIST, ArrayList(exposureEvent.source)) }
jumpActivity(context, bundle)
}
@ -1365,10 +1392,11 @@ object DirectUtils {
* 跳转到开服表
*/
@JvmStatic
fun directToGameServers(context: Context, entrance: String, path: String) {
fun directToGameServers(context: Context, entrance: String, path: String, exposureEvent: ExposureEvent? = null) {
val bundle = Bundle()
bundle.putString(KEY_TO, GameServersActivity::class.java.name)
bundle.putString(KEY_ENTRANCE, ToolBarActivity.mergeEntranceAndPath(entrance, path))
exposureEvent?.let { bundle.putParcelableArrayList(KEY_EXPOSURE_SOURCE_LIST, ArrayList(exposureEvent.source)) }
jumpActivity(context, bundle)
}
@ -1818,7 +1846,8 @@ object DirectUtils {
collectionId: String,
blockId: String = "",
blockName: String = "",
entrance: String = ""
entrance: String = "",
exposureEvent: ExposureEvent? = null
) {
if (collectionId.isEmpty()) return
val bundle = Bundle()
@ -1827,6 +1856,7 @@ object DirectUtils {
bundle.putString(KEY_BLOCK_NAME, blockName)
bundle.putString(KEY_ENTRANCE, entrance)
bundle.putString(KEY_COLLECTION_ID, collectionId)
exposureEvent?.let { bundle.putParcelableArrayList(KEY_EXPOSURE_SOURCE_LIST, ArrayList(exposureEvent.source)) }
jumpActivity(context, bundle)
}
@ -1862,13 +1892,20 @@ object DirectUtils {
* 跳转至游戏单详情
*/
@JvmStatic
fun directToGameCollectionDetail(context: Context, id: String, entrance: String? = null, path: String? = null) {
fun directToGameCollectionDetail(
context: Context,
id: String,
entrance: String? = null,
path: String? = null,
exposureEvent: ExposureEvent? = null
) {
if (id.isEmpty()) return
val bundle = Bundle()
bundle.putString(KEY_ENTRANCE, entrance ?: ENTRANCE_BROWSER)
bundle.putString(KEY_PATH, path)
bundle.putString(KEY_TO, GameCollectionDetailActivity::class.java.name)
bundle.putString(KEY_GAME_COLLECTION_ID, id)
exposureEvent?.let { bundle.putParcelableArrayList(KEY_EXPOSURE_SOURCE_LIST, ArrayList(exposureEvent.source)) }
jumpActivity(context, bundle)
}

View File

@ -7,7 +7,6 @@ import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.collection.ArrayMap
import androidx.recyclerview.widget.RecyclerView
import com.gh.gamecenter.common.base.GlobalActivityManager
import com.gh.common.chain.*
import com.gh.common.constant.Config
import com.gh.common.dialog.DeviceRemindDialog
@ -25,6 +24,7 @@ import com.gh.download.dialog.DownloadDialog
import com.gh.gamecenter.R
import com.gh.gamecenter.WebActivity
import com.gh.gamecenter.adapter.viewholder.GameViewHolder
import com.gh.gamecenter.common.base.GlobalActivityManager
import com.gh.gamecenter.common.callback.CancelListener
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.constant.EntranceConsts
@ -836,6 +836,7 @@ object DownloadItemUtils {
addHandler(CertificationHandler())
addHandler(VersionNumberHandler())
addHandler(OverseaDownloadHandler())
addHandler(CheckStoragePermissionHandler())
addHandler(ValidateVSpaceHandler())
addHandler(CheckDownloadHandler())
}
@ -927,7 +928,12 @@ object DownloadItemUtils {
}
DownloadDialogHelper.findAvailableDialogAndShow(context, gameEntity, apk, object : EmptyCallback {
override fun onCallback() {
DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean ->
DialogUtils.checkDownload(
context,
apk.size,
gameEntity.id,
gameEntity.name
) { isSubscribe: Boolean ->
update(context, gameEntity, entrance, location, isSubscribe, traceEvent)
}
}
@ -1070,6 +1076,7 @@ object DownloadItemUtils {
"game_type", gameEntity.categoryChinese,
"download_status", gameEntity.downloadStatusChinese,
"button_name", buttonName,
"game_schema_type", gameEntity.gameBitChinese,
"page_name", GlobalActivityManager.getCurrentPageEntity().pageName,
"page_id", GlobalActivityManager.getCurrentPageEntity().pageId,
"page_business_id", GlobalActivityManager.getCurrentPageEntity().pageBusinessId,

View File

@ -1,7 +1,5 @@
package com.gh.common.util
import com.gh.gamecenter.common.base.GlobalActivityManager.getCurrentPageEntity
import com.gh.gamecenter.common.base.GlobalActivityManager.getLastPageEntity
import com.gh.common.constant.Config
import com.gh.common.exposure.ExposureUtils
import com.gh.common.simulator.SimulatorDownloadManager
@ -10,6 +8,8 @@ import com.gh.common.xapk.XapkInstaller
import com.gh.download.DownloadDataHelper
import com.gh.download.DownloadManager
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.GlobalActivityManager.getCurrentPageEntity
import com.gh.gamecenter.common.base.GlobalActivityManager.getLastPageEntity
import com.gh.gamecenter.common.base.activity.BaseActivity
import com.gh.gamecenter.common.callback.ConfirmListener
import com.gh.gamecenter.common.constant.Constants
@ -18,7 +18,6 @@ import com.gh.gamecenter.common.entity.SuggestType
import com.gh.gamecenter.common.eventbus.EBShowDialog
import com.gh.gamecenter.common.retrofit.Response
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.utils.SensorsBridge
import com.gh.gamecenter.core.utils.*
import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.gh.gamecenter.feature.entity.GameEntity
@ -235,17 +234,13 @@ object DownloadObserver {
downloadEntity.name + " - " + platform + " - 下载完成"
)
else -> {
if (downloadEntity.isVGame()) {
VHelper.showFloatingWindow(downloadEntity.packageName)
} else {
if (!downloadEntity.isVGame()) {
Utils.toast(mApplication, downloadEntity.name + " - 下载完成")
}
}
}
} else {
if (downloadEntity.isVGame()) {
VHelper.showFloatingWindow(downloadEntity.packageName)
} else {
if (!downloadEntity.isVGame()) {
Utils.toast(mApplication, downloadEntity.name + " - 下载完成")
}
}
@ -281,7 +276,7 @@ object DownloadObserver {
val downloadType = downloadEntity.getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE)
// 是否是自动安装
val isAutoInstall = SPUtils.getBoolean(Constants.SP_AUTO_INSTALL, true)
if (downloadType == Constants.SIMULATOR_DOWNLOAD || isAutoInstall) {
if (downloadType != Constants.VSPACE_32_DOWNLOAD_ONLY && (downloadType == Constants.SIMULATOR_DOWNLOAD || isAutoInstall)) {
if (FileUtils.isEmptyFile(downloadEntity.path)) {
Utils.toast(mApplication, R.string.install_failure_hint)
downloadManager.cancel(downloadEntity.url)
@ -317,9 +312,6 @@ object DownloadObserver {
}
}
}
// 统计下载完成
uploadData(gameId, downloadEntity.platform)
}
// 下载过程分析统计
@ -386,14 +378,22 @@ object DownloadObserver {
SensorsBridge.trackEvent(
"HaloFunGameDownloadDone",
"game_name", downloadEntity.name,
"game_id", downloadEntity.gameId
"game_id", downloadEntity.gameId,
"game_schema_type", if (downloadEntity.getMetaExtra(VHelper.KEY_BIT) == "32") "32位" else "64位"
)
} else if (downloadEntity.gameId != "62bd412bbbf04747cd3de539") {
} else if (downloadEntity.gameId == Constants.HALO_FUN_GAME_ID) {
SensorsBridge.trackEvent(
"HaloFunDownloadDone",
"space_schema_type",
if (downloadEntity.packageName == VHelper.VSPACE_32BIT_PACKAGENAME) "32位" else "64位"
)
} else if (downloadEntity.gameId != Constants.GHZS_GAME_ID && downloadEntity.getMetaExtra(Constants.EXTRA_DOWNLOAD_TYPE) != Constants.SIMULATOR_DOWNLOAD) {
SensorsBridge.trackEvent(
"DownloadProcessFinish",
"game_id", downloadEntity.gameId,
"game_name", downloadEntity.meta[Constants.GAME_NAME] ?: "",
"game_type", downloadEntity.meta[Constants.GAME_TYPE] ?: "",
"game_schema_type", if (downloadEntity.getMetaExtra(VHelper.KEY_BIT) == "32") "32位" else "64位",
"page_name", getCurrentPageEntity().pageName,
"page_id", getCurrentPageEntity().pageId,
"page_business_id", getCurrentPageEntity().pageBusinessId,
@ -452,19 +452,4 @@ object DownloadObserver {
DataLogUtils.uploadHijack(mApplication, downloadEntity)
}
// 统计下载
private fun uploadData(id: String, platform: String?) {
val params = HashMap<String, String>()
params["game"] = id
params["platform"] = platform ?: ""
val body = RequestBody.create(
MediaType.parse("application/json"),
JSONObject(params as Map<*, *>).toString()
)
RetrofitManager.getInstance().api.postDownload(body)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(Response())
}
}

View File

@ -221,7 +221,7 @@ object GameActivityDownloadHelper {
) {
GamePermissionDialogFragment.show((context as AppCompatActivity), gameEntity, gameEntity.info) {
CertificationDialog.showCertificationDialog(context, gameEntity) {
DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean ->
DialogUtils.checkDownload(context, apk.size, gameEntity.id, gameEntity.name) { isSubscribe: Boolean ->
download(context, gameEntity, apk, isSubscribe, entrance, location, traceEvent)
}
}
@ -241,7 +241,12 @@ object GameActivityDownloadHelper {
VHelper.validateVSpaceBeforeAction(context, gameEntity) {
GamePermissionDialogFragment.show((context as AppCompatActivity), gameEntity, gameEntity.info) {
CertificationDialog.showCertificationDialog(context, gameEntity) {
DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean ->
DialogUtils.checkDownload(
context,
apk.size,
gameEntity.id,
gameEntity.name
) { isSubscribe: Boolean ->
download(context, gameEntity, apk, isSubscribe, entrance, location, traceEvent)
}
}
@ -262,7 +267,7 @@ object GameActivityDownloadHelper {
DownloadDialog.showDownloadDialog(context, gameEntity, traceEvent, entrance, location)
} else {
CertificationDialog.showCertificationDialog(context, gameEntity) {
DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean ->
DialogUtils.checkDownload(context, apk.size, gameEntity.id, gameEntity.name) { isSubscribe: Boolean ->
plugin(context, gameEntity, apk, entrance, location, isSubscribe, traceEvent)
}
}
@ -355,7 +360,7 @@ object GameActivityDownloadHelper {
location: String,
traceEvent: ExposureEvent
) {
DialogUtils.checkDownload(context, apk.size) { isSubscribe: Boolean ->
DialogUtils.checkDownload(context, apk.size, gameEntity.id, gameEntity.name) { isSubscribe: Boolean ->
update(context, gameEntity, apk, entrance, location, isSubscribe, traceEvent)
}
}

View File

@ -5,7 +5,6 @@ import com.gh.gamecenter.common.json.JsonObjectBuilder
import com.gh.gamecenter.common.json.json
import com.gh.gamecenter.common.loghub.LoghubUtils
import com.gh.gamecenter.common.utils.LogUtils
import com.gh.gamecenter.common.utils.NewFlatLogUtils
import com.gh.gamecenter.entity.HomeSubSlide
import com.lightgame.utils.Utils
import org.json.JSONArray
@ -54,6 +53,66 @@ object NewFlatLogUtils {
log(json)
}
// 畅玩助手下载弹窗展示事件
@JvmStatic
fun logHaloFunDownloadDialogShow(gameId: String, gameName: String, gameArchitecture: String) {
val json = json {
KEY_EVENT to "halo_fun_download_dialog_show"
"game_id" to gameId
"game_name" to gameName
"game_architecture" to gameArchitecture
parseAndPutMeta().invoke(this)
}
log(json)
}
// 畅玩助手下载点击事件
@JvmStatic
fun logHaloFunDownloadDialogDownloadClick(architecture: String) {
val json = json {
KEY_EVENT to "halo_fun_download_dialog_download_click"
"architecture" to architecture
parseAndPutMeta().invoke(this)
}
log(json)
}
// 畅玩助手安装提示弹窗展示事件
@JvmStatic
fun logHaloFunInstallTipDialogShow(architecture: String) {
val json = json {
KEY_EVENT to "halo_fun_install_tip_dialog_show"
"architecture" to architecture
parseAndPutMeta().invoke(this)
}
log(json)
}
// 畅玩助手更新弹窗展示事件
@JvmStatic
fun logHaloFunUpdateDialogShow(gameId: String, gameName: String, gameArchitecture: String) {
val json = json {
KEY_EVENT to "halo_fun_update_dialog_show"
"game_id" to gameId
"game_name" to gameName
"game_architecture" to gameArchitecture
parseAndPutMeta().invoke(this)
}
log(json)
}
// 畅玩助手32位弹窗事件
@JvmStatic
fun logHaloFun32DialogEvent(event: String, gameId: String, gameName: String) {
val json = json {
KEY_EVENT to event
"game_id" to gameId
"game_name" to gameName
parseAndPutMeta().invoke(this)
}
log(json)
}
// 关联游戏跳转icon点击事件
@JvmStatic
fun logHaloFunGameDetailJumpClick(downloadStatus: String, gameId: String) {
@ -80,11 +139,12 @@ object NewFlatLogUtils {
// 畅玩助手更新弹窗点击事件
@JvmStatic
fun logHaloFunUpdateDialogClick(dialogType: String, buttonType: String) {
fun logHaloFunUpdateDialogClick(dialogType: String, buttonType: String, architecture: String) {
val json = json {
KEY_EVENT to "halo_fun_update_dialog_click"
"dialog_type" to dialogType
KEY_BUTTON_TYPE to buttonType
"architecture" to architecture
parseAndPutMeta().invoke(this)
}
log(json)
@ -2100,4 +2160,29 @@ object NewFlatLogUtils {
}
log(json)
}
// 下载流量提示弹窗展示事件
@JvmStatic
fun logDownloadMobileDataDialogShow(gameId: String, gameName: String) {
val json = json {
KEY_EVENT to "download_mobile_data_dialog_show"
KEY_GAME_ID to gameId
KEY_GAME_NAME to gameName
parseAndPutMeta().invoke(this)
}
log(json, "event", false)
}
// 下载流量提示弹窗点击事件
@JvmStatic
fun logDownloadMobileDataDialogClick(gameId: String, gameName: String, button: String) {
val json = json {
KEY_EVENT to "download_mobile_data_dialog_click"
KEY_GAME_ID to gameId
KEY_GAME_NAME to gameName
"button" to button
parseAndPutMeta().invoke(this)
}
log(json, "event", false)
}
}

View File

@ -38,6 +38,7 @@ import com.gh.gamecenter.manager.PackagesManager;
import com.gh.vspace.VHelper;
import com.gh.vspace.db.VGameEntity;
import com.halo.assistant.HaloApp;
import com.lg.vspace.VirtualAppManager;
import com.lightgame.utils.Utils;
import net.dongliu.apk.parser.ApkFile;
@ -554,9 +555,32 @@ public class PackageUtils {
}
}
/**
* 根据包名,判断是否已安装该游戏
* 不区分是否有桌面图标
*/
public static boolean isInstalledFromAllPackage(Context context, String packageName) {
ArrayList<String> allPackageName = getAllPackageName(context);
return allPackageName.contains(packageName);
try {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) {
context.getPackageManager().getPackageInfo(
packageName,
PackageManager.PackageInfoFlags.of(0)
);
} else {
context.getPackageManager().getPackageInfo(packageName, 0);
}
return true;
} catch (Exception e) {
ArrayList<String> allPackageName = getAllPackageName(context);
boolean isInstalled = allPackageName.contains(packageName);
if (isInstalled) {
// 能进这里说明上面的 try {} 结果有问题,记录一下
SentryHelper.INSTANCE.onEvent("CHECK_INSTALLED_CONFLICT", "packageName", packageName);
}
return isInstalled;
}
}
/*

View File

@ -16,6 +16,9 @@ object RealNameHelper {
var pendingInstallPkgPath = ""
// 0表示未实名1表示未成年2表示成年
private var mCertificationStatus: Int = 0
/**
* 弹未成年人不能下载游戏弹窗
*/
@ -124,7 +127,21 @@ object RealNameHelper {
DownloadManager.getInstance()
.addInvisiblePendingTask(downloadEntity)
}
}
/**
* 获取实名状态 0表示未实名1表示未成年2表示成年
*/
fun getCertificationStatus(): Int {
return mCertificationStatus
}
/**
* 更新实名状态 0表示未实名1表示未成年2表示成年
*/
@JvmStatic
fun updateCertificationStatus(newCertificationStatus: Int) {
mCertificationStatus = newCertificationStatus
}
}

View File

@ -3,6 +3,7 @@ package com.gh.download
import android.content.pm.PackageInfo
import android.text.TextUtils
import com.gh.common.util.PackageUtils
import com.gh.common.util.RealNameHelper
import com.gh.common.xapk.XapkInstaller
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.exposure.meta.MetaUtil
@ -125,6 +126,7 @@ object DownloadDataHelper {
payloadObject.put("gameName", downloadEntity.name)
payloadObject.put("platform", downloadEntity.platform)
payloadObject.put("package", downloadEntity.packageName)
payloadObject.put("certification", RealNameHelper.getCertificationStatus())
payloadObject.put("filename", getFileName(downloadEntity))
payloadObject.put("task_num", NDataChanger.downloadingTasks.size)
jsonObject.put("payload", payloadObject)
@ -209,6 +211,7 @@ object DownloadDataHelper {
payloadObject.put("gameName", downloadEntity.name)
payloadObject.put("platform", downloadEntity.platform)
payloadObject.put("package", downloadEntity.packageName)
payloadObject.put("certification", RealNameHelper.getCertificationStatus())
payloadObject.put("filename", getFileName(downloadEntity))
payloadObject.put("launch_ms", startupTime)
payloadObject.put("task_num", NDataChanger.downloadingTasks.size)
@ -247,6 +250,7 @@ object DownloadDataHelper {
payloadObject.put("gameName", downloadEntity.name)
payloadObject.put("platform", downloadEntity.platform)
payloadObject.put("package", downloadEntity.packageName)
payloadObject.put("certification", RealNameHelper.getCertificationStatus())
payloadObject.put("filename", getFileName(downloadEntity))
payloadObject.put("total_size", sizeInMB)
if (parallel != null) {
@ -317,6 +321,7 @@ object DownloadDataHelper {
payloadObject.put("gameName", downloadEntity.name)
payloadObject.put("platform", downloadEntity.platform)
payloadObject.put("package", downloadEntity.packageName)
payloadObject.put("certification", RealNameHelper.getCertificationStatus())
payloadObject.put("filename", getFileName(downloadEntity))
payloadObject.put("speed_progress", JSONArray(averageSpeedList))
payloadObject.put("is_finished", downloadEntity.status == DownloadStatus.done)
@ -356,6 +361,7 @@ object DownloadDataHelper {
sheet.put("game_id", downloadEntity.gameId)
sheet.put("platform", downloadEntity.platform)
sheet.put("package", downloadEntity.packageName)
sheet.put("certification", RealNameHelper.getCertificationStatus())
sheet.put("filename", getFileName(downloadEntity))
sheet.put("total_size", downloadEntity.size / 1024 / 1024)
sheet.put("current_progress_size", downloadEntity.progress / 1024)

View File

@ -341,15 +341,18 @@ public class DownloadManager implements DownloadStatusListener {
ExtensionsKt.addMetaExtra(downloadEntity, Constants.EXTRA_DOWNLOAD_TYPE, Constants.SMOOTH_GAME);
ExtensionsKt.addMetaExtra(downloadEntity, DownloadConfig.KEY_PROGRESS_CALLBACK_INTERVAL, "200");
ExtensionsKt.addMetaExtra(downloadEntity, VHelper.KEY_REQUIRED_G_APPS, gameEntity.getGAppsSwitch());
ExtensionsKt.addMetaExtra(downloadEntity, VHelper.KEY_BIT, apkEntity.getBit());
SensorsBridge.trackEvent("HaloFunGameDownloadClick",
"game_name", gameEntity.getName(),
"game_id", gameEntity.getId());
"game_id", gameEntity.getId(),
"game_schema_type", gameEntity.getGameBitChinese());
} else {
SensorsBridge.trackEvent("DownloadProcessBegin",
"game_id", gameEntity.getId(),
"game_name", gameEntity.getName(),
"game_type", gameEntity.getCategoryChinese(),
"game_schema_type", gameEntity.getGameBitChinese(),
"page_name", GlobalActivityManager.getCurrentPageEntity().getPageName(),
"page_id", GlobalActivityManager.getCurrentPageEntity().getPageId(),
"page_business_id", GlobalActivityManager.getCurrentPageEntity().getPageBusinessId(),

View File

@ -145,7 +145,8 @@ object PackageObserver {
mDownloadEntity?.let {
if (it.isVGame()) return@let
if (it.isPluggable || it.isUpdate) {
if (it.isPluggable
|| (it.isUpdate && !PackageUtils.isInstalled(application, it.packageName))) {
PackageInstaller.install(application, mDownloadEntity)
}
}

View File

@ -373,7 +373,9 @@ class DownloadDialogItemViewHolder(val binding: DownloadDialogItemBinding) : Bas
override fun onConfirm() {
DialogUtils.checkDownload(
context,
apkEntity.size
apkEntity.size,
gameEntity.id,
gameEntity.name
) { isSubscribe ->
DownloadManager.createDownload(
context,

View File

@ -27,7 +27,7 @@ class BlockActivity : DownloadToolbarActivity() {
}
override fun provideNormalIntent(): Intent {
return getTargetIntent(this, BlockActivity::class.java, GameFragment::class.java)
return getTargetIntent(this, BlockActivity::class.java, GameFragment::class.java, intent?.extras)
}
override fun showDownloadMenu(): Boolean {

View File

@ -474,6 +474,8 @@ public class MainActivity extends BaseActivity {
protected void onDestroy() {
super.onDestroy();
if (mStartUpAdProvider != null) mStartUpAdProvider.cancelStartUpAd(this);
handler.removeCallbacksAndMessages(null);
releaseExoSourceCache();
}
@ -500,7 +502,6 @@ public class MainActivity extends BaseActivity {
if (!showAd) {
hideStartUp();
hideStartUpAd();
hideSDKStartUpAd();
return;
}
final StartupAdEntity startUp = AdHelper.getStartUp();
@ -612,16 +613,10 @@ public class MainActivity extends BaseActivity {
startAdContainer.setVisibility(View.GONE);
ExtensionsKt.removeFromParent(startAdContainer);
}
checkDialog();
}
private void hideSDKStartUpAd() {
showAd = false;
getIntent().putExtra(SHOW_AD, false);
View startAdContainer = findViewById(R.id.sdkStartAdContainer);
if (startAdContainer != null) {
startAdContainer.setVisibility(View.GONE);
ExtensionsKt.removeFromParent(startAdContainer);
View startSdkAdContainer = findViewById(R.id.sdkStartAdContainer);
if (startSdkAdContainer != null) {
startSdkAdContainer.setVisibility(View.GONE);
ExtensionsKt.removeFromParent(startSdkAdContainer);
if (mStartUpAdProvider != null) mStartUpAdProvider.cancelStartUpAd(this);
}
checkDialog();
@ -687,7 +682,7 @@ public class MainActivity extends BaseActivity {
FrameLayout adsFl = findViewById(R.id.adsFl);
if (mStartUpAdProvider != null) {
mStartUpAdProvider.initStartUpAd(startAdContainer, adsFl, showAd, () -> {
hideSDKStartUpAd();
hideStartUpAd();
return null;
});
}

View File

@ -30,7 +30,6 @@ import com.ethanhua.skeleton.ViewSkeletonScreen;
import com.gh.base.DownloadToolbarActivity;
import com.gh.common.filter.RegionSettingHelper;
import com.gh.common.history.HistoryHelper;
import com.gh.gamecenter.feature.utils.ApkActiveUtils;
import com.gh.common.util.CheckLoginUtils;
import com.gh.common.util.CollectionUtils;
import com.gh.common.util.DataCollectionUtils;
@ -41,6 +40,8 @@ import com.gh.gamecenter.adapter.viewholder.DetailViewHolder;
import com.gh.gamecenter.common.callback.OnRequestCallBackListener;
import com.gh.gamecenter.common.constant.Constants;
import com.gh.gamecenter.common.constant.EntranceConsts;
import com.gh.gamecenter.common.eventbus.EBNetworkState;
import com.gh.gamecenter.common.eventbus.EBReuse;
import com.gh.gamecenter.common.retrofit.Response;
import com.gh.gamecenter.common.utils.ExtensionsKt;
import com.gh.gamecenter.common.utils.ShareUtils;
@ -49,15 +50,16 @@ import com.gh.gamecenter.common.view.VerticalItemDecoration;
import com.gh.gamecenter.core.utils.ClickUtils;
import com.gh.gamecenter.core.utils.DisplayUtils;
import com.gh.gamecenter.core.utils.MtaHelper;
import com.gh.gamecenter.entity.NewsDetailEntity;
import com.gh.gamecenter.eventbus.EBConcernChanged;
import com.gh.gamecenter.eventbus.EBAddComment;
import com.gh.gamecenter.eventbus.EBDeleteComment;
import com.gh.gamecenter.eventbus.EBDownloadStatus;
import com.gh.gamecenter.eventbus.EBPackage;
import com.gh.gamecenter.feature.entity.GameEntity;
import com.gh.gamecenter.feature.entity.MeEntity;
import com.gh.gamecenter.entity.NewsDetailEntity;
import com.gh.gamecenter.feature.entity.NewsEntity;
import com.gh.gamecenter.eventbus.EBConcernChanged;
import com.gh.gamecenter.eventbus.EBDownloadStatus;
import com.gh.gamecenter.common.eventbus.EBNetworkState;
import com.gh.gamecenter.eventbus.EBPackage;
import com.gh.gamecenter.common.eventbus.EBReuse;
import com.gh.gamecenter.feature.utils.ApkActiveUtils;
import com.gh.gamecenter.newsdetail.NewsDetailAdapter;
import com.gh.gamecenter.retrofit.RetrofitManager;
import com.lightgame.download.DataWatcher;
@ -557,6 +559,17 @@ public class NewsDetailActivity extends DownloadToolbarActivity implements OnCli
});
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onDeleteComment(EBDeleteComment event) {
adapter.getNewsCommentNum();
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onAddComment(EBAddComment event) {
adapter.getNewsCommentNum();
}
@Override
public boolean dispatchTouchEvent(MotionEvent ev) {
switch (ev.getAction() & MotionEventCompat.ACTION_MASK) {

View File

@ -149,7 +149,7 @@ public class SkipActivity extends BaseActivity {
if (!TextUtils.isEmpty(qaId)) {
DirectUtils.directToQa(this, qaTitle, qaId);
} else if ("vgame".equals(suggestionType)) {
DirectUtils.directToFeedbackCompat(this, content, "game", isQaFeedback, qaContentId, EntranceConsts.ENTRANCE_BROWSER);
DirectUtils.directToVGameFeedback(this, content, "game", isQaFeedback, qaContentId, EntranceConsts.ENTRANCE_BROWSER);
} else {
DirectUtils.directToFeedback(this, content, null, isQaFeedback, qaContentId, EntranceConsts.ENTRANCE_BROWSER);
}
@ -328,11 +328,11 @@ public class SkipActivity extends BaseActivity {
entity.setLink(path);
entity.setName(name);
entity.setText(name);
DirectUtils.directToBlock(this, entity, mEntrance);
DirectUtils.directToBlock(this, entity, mEntrance, null);
break;
case EntranceConsts.HOST_SERVER_BLOCK:
DirectUtils.directToGameServers(this, ENTRANCE_BROWSER, "浏览器");
DirectUtils.directToGameServers(this, ENTRANCE_BROWSER, "浏览器", null);
break;
case EntranceConsts.HOST_AMWAY_BLOCK:
@ -400,7 +400,7 @@ public class SkipActivity extends BaseActivity {
DirectUtils.directToHelpAndFeedback(this, TextUtils.isEmpty(position) ? 0 : Integer.parseInt(position));
break;
case HOST_GAME_COLLECTION_DETAIL:
DirectUtils.directToGameCollectionDetail(this, path, ENTRANCE_BROWSER, "");
DirectUtils.directToGameCollectionDetail(this, path, ENTRANCE_BROWSER, "", null);
break;
case HOST_GAME_COLLECTION_SQUARE:
DirectUtils.directToGameCollectionSquare(this, ENTRANCE_BROWSER, "", "", "");

View File

@ -164,9 +164,11 @@ class SplashScreenActivity : BaseActivity() {
val signatureHash = packageUtilsConfig?.getApkSignatureByPackageName(this, packageName)?.get(0)
val sideLoadInfo = packageUtilsConfig?.getSideLoadedInfo()
val trackEvent = JSONObject()
// 是否首次使用神策
val isFirstTime = SPUtils.getBoolean(Constants.SP_SENSORS_IS_FIRST_TIME, true)
tryCatchInRelease {
trackEvent.run {
put("\$is_first_time", SPUtils.getBoolean(Constants.SP_SENSORS_IS_FIRST_TIME, true))
put("\$is_first_time", isFirstTime)
put("is_side_loaded", sideLoadInfo?.get("is_side_loaded").toBoolean())
put("installer_store", sideLoadInfo?.get("installer_store") ?: "")
put("package_name", packageName)
@ -176,6 +178,10 @@ class SplashScreenActivity : BaseActivity() {
}
}
SensorsBridge.trackEvent("AppLaunch", trackEvent)
if (!isFirstTime && HaloApp.getInstance().isBrandNewInstall) {
// 神策不是第一次使用,但是全局标志为全新安装,有问题,上报数据供后续确认
SentryHelper.onEvent("WRONG_LAUNCH_LOG", "a_id", MetaUtil.getBase64EncodedAndroidId())
}
SPUtils.setBoolean(Constants.SP_SENSORS_IS_FIRST_TIME, false)
}
@ -306,7 +312,7 @@ class SplashScreenActivity : BaseActivity() {
private fun doFlavorInit() {
HaloApp.getInstance().flavorProvider.init(HaloApp.getInstance(), this, PkgHelper.getActivateRatio())
val whiteListChannel = arrayListOf<String>(
val whiteListChannel = arrayListOf(
"GH_206",
"KS-GHZS-KY1",
"KS-GHZS-MC1",
@ -326,12 +332,6 @@ class SplashScreenActivity : BaseActivity() {
private fun initStartUpAdSDK() {
mStartUpAdProvider?.run {
if (shouldEnableSDK(HaloApp.getInstance().channel)) {
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {
initOAID(applicationContext) {
HaloApp.getInstance().oaid = it
MetaUtil.refreshMeta()
}
}
initSDK(applicationContext)
}
}

View File

@ -8,27 +8,31 @@ import android.view.ViewGroup;
import androidx.recyclerview.widget.RecyclerView;
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
import com.gh.gamecenter.common.constant.ItemViewType;
import com.gh.common.util.CheckLoginUtils;
import com.gh.common.util.CommentUtils;
import com.gh.common.util.DialogUtils;
import com.gh.common.util.DirectUtils;
import com.gh.gamecenter.common.utils.ImageUtils;
import com.gh.gamecenter.core.utils.MtaHelper;
import com.gh.gamecenter.common.utils.TextHelper;
import com.gh.gamecenter.R;
import com.gh.gamecenter.adapter.viewholder.CommentViewHolder;
import com.gh.gamecenter.common.constant.ItemViewType;
import com.gh.gamecenter.common.retrofit.Response;
import com.gh.gamecenter.common.utils.ImageUtils;
import com.gh.gamecenter.common.utils.TextHelper;
import com.gh.gamecenter.common.viewholder.FooterViewHolder;
import com.gh.gamecenter.core.utils.MtaHelper;
import com.gh.gamecenter.entity.ArticleCommentParent;
import com.gh.gamecenter.entity.CommentEntity;
import com.gh.gamecenter.common.retrofit.Response;
import com.gh.gamecenter.eventbus.EBDeleteComment;
import com.gh.gamecenter.retrofit.RetrofitManager;
import com.lightgame.adapter.BaseRecyclerAdapter;
import com.lightgame.utils.Utils;
import org.greenrobot.eventbus.EventBus;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
@ -68,22 +72,34 @@ public class CommentDetailAdapter extends BaseRecyclerAdapter<ViewHolder> {
mDataExceptionView = dataExceptionView;
mRecyclerView = recyclerView;
loadData();
mOnCommentCallBackListener.onCommentCallback(null);
refresh();
}
public void loadData() {
public void refresh() {
loadData(1);
}
public void loadMore() {
loadData(mPage + 1);
}
public void loadData(int page) {
if (mIsLoading) return;
mIsLoading = true;
RetrofitManager.getInstance().getApi()
.getCommentTrace(mCommentId, mPage)
.getCommentTrace(mCommentId, page)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Response<List<CommentEntity>>() {
@Override
public void onResponse(List<CommentEntity> response) {
super.onResponse(response);
if (page == 1) {
mCommentList.clear();
}
mCommentList.addAll(response);
if (response.size() < 20) {
mIsOver = true;
}
@ -91,7 +107,7 @@ public class CommentDetailAdapter extends BaseRecyclerAdapter<ViewHolder> {
mDataExceptionView.setVisibility(View.GONE);
mRecyclerView.setVisibility(View.VISIBLE);
notifyItemRangeChanged(0, getItemCount() - 1);
mPage++;
mPage = page;
mIsLoading = false;
}
@ -201,8 +217,14 @@ public class CommentDetailAdapter extends BaseRecyclerAdapter<ViewHolder> {
});
holder.commentMore.setOnClickListener(v ->
CommentUtils.showReportDialog(commentEntity,
mContext, false, "资讯文章-评论"));
CommentUtils.showMorePopupWindow(
holder.commentMore,
commentEntity,
false,
"资讯文章-评论",
() -> EventBus.getDefault().post(new EBDeleteComment(commentEntity))
)
);
holder.commentUserIconDv.setOnClickListener(v -> DirectUtils.directToHomeActivity(mContext, commentEntity.getUser().getId(), "", "文章-评论详情"));
holder.commentUserNameTv.setOnClickListener(v -> DirectUtils.directToHomeActivity(mContext, commentEntity.getUser().getId(), "", "文章-评论详情"));
@ -254,4 +276,24 @@ public class CommentDetailAdapter extends BaseRecyclerAdapter<ViewHolder> {
public boolean isLoading() {
return mIsLoading;
}
public void notifyCommentRemoved(final CommentEntity entity) {
int positionInComments = getCommentIndexByEntity(mCommentList, entity);
if (positionInComments != -1) {
mCommentList.remove(positionInComments);
notifyItemRemoved(positionInComments);
}
}
private static int getCommentIndexByEntity(
final List<CommentEntity> commentList,
final CommentEntity comment
) {
for (int i = 0; i < commentList.size();i++) {
if (Objects.equals(comment.getId(), commentList.get(i).getId())) {
return i;
}
}
return -1;
}
}

View File

@ -42,6 +42,7 @@ import com.gh.gamecenter.databinding.NewsDigestItemBinding;
import com.gh.gamecenter.entity.ArticleCommentParent;
import com.gh.gamecenter.entity.CommentEntity;
import com.gh.gamecenter.entity.ConcernEntity;
import com.gh.gamecenter.eventbus.EBDeleteComment;
import com.gh.gamecenter.manager.VisitManager;
import com.gh.gamecenter.common.retrofit.JSONObjectResponse;
import com.gh.gamecenter.common.retrofit.OkHttpCache;
@ -50,12 +51,14 @@ import com.gh.gamecenter.retrofit.RetrofitManager;
import com.lightgame.adapter.BaseRecyclerAdapter;
import com.lightgame.utils.Utils;
import org.greenrobot.eventbus.EventBus;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.Timer;
import java.util.TimerTask;
import java.util.concurrent.atomic.AtomicBoolean;
@ -151,6 +154,7 @@ public class MessageDetailAdapter extends BaseRecyclerAdapter<ViewHolder> {
return;
}
if (isRefresh) {
isOver = false;
mNormalCommentList.clear();
mPage = 1;
}
@ -467,8 +471,14 @@ public class MessageDetailAdapter extends BaseRecyclerAdapter<ViewHolder> {
});
holder.commentMore.setOnClickListener(v ->
CommentUtils.showReportDialog(finalCommentEntity,
mContext, true, "资讯文章详情-评论详情"));
CommentUtils.showMorePopupWindow(
holder.commentMore,
finalCommentEntity,
true,
"资讯文章详情-评论详情",
() -> EventBus.getDefault().post(new EBDeleteComment(finalCommentEntity))
)
);
holder.commentUserNameTv.setOnClickListener(v -> DirectUtils.directToHomeActivity(mContext, finalCommentEntity.getUser().getId(), mEntrance, "文章-评论详情"));
holder.commentUserIconDv.setOnClickListener(v -> DirectUtils.directToHomeActivity(mContext, finalCommentEntity.getUser().getId(), mEntrance, "文章-评论详情"));
@ -524,6 +534,42 @@ public class MessageDetailAdapter extends BaseRecyclerAdapter<ViewHolder> {
});
}
public void notifyCommentRemoved(final CommentEntity entity) {
if (mHotCommentList.size() > 0) {
int positionInHotComments = getCommentIndexByEntity(mHotCommentList, entity);
if (positionInHotComments != -1) {// 如果在热门评论中存在要被删除的评论,则将此评论移除
mHotCommentList.remove(positionInHotComments);
}
}
if (mNormalCommentList.size() > 0) {
int positionInNormalComments = getCommentIndexByEntity(mNormalCommentList, entity);
if (positionInNormalComments != -1) {// 如果在热门评论中存在要被删除的评论,则将此评论移除
mNormalCommentList.remove(positionInNormalComments);
}
}
if (mConcernEntity != null) {
int commentNum = mConcernEntity.getCommentnum();
mConcernEntity.setCommentnum(commentNum - 1);
}
notifyDataSetChanged();
}
private static int getCommentIndexByEntity(
final List<CommentEntity> commentList,
final CommentEntity comment
) {
for (int i = 0; i < commentList.size();i++) {
if (Objects.equals(comment.getId(), commentList.get(i).getId())) {
return i;
}
}
return -1;
}
private void statNewsViews(final String news_id) {
RetrofitManager.getInstance().getApi().postArticleVisit(news_id)
.subscribeOn(Schedulers.io())
@ -587,7 +633,7 @@ public class MessageDetailAdapter extends BaseRecyclerAdapter<ViewHolder> {
}
public void addCommentCount() {
mConcernEntity.setCommentnum(mConcernEntity.getCommentnum());
mConcernEntity.setCommentnum(mConcernEntity.getCommentnum() + 1);
notifyDataSetChanged();
}

View File

@ -166,6 +166,7 @@ public class DetailViewHolder {
"game_type", mGameEntity.getCategoryChinese(),
"download_status", mGameEntity.getDownloadStatusChinese(),
"button_name", mViewHolder.mDownloadPb.getText(),
"game_schema_type", mGameEntity.getGameBitChinese(),
"page_name", GlobalActivityManager.getCurrentPageEntity().getPageName(),
"page_id", GlobalActivityManager.getCurrentPageEntity().getPageId(),
"page_business_id", GlobalActivityManager.getCurrentPageEntity().getPageBusinessId(),
@ -285,9 +286,9 @@ public class DetailViewHolder {
ChainBuilder builder = new ChainBuilder();
builder.addHandler(new UpdateNewSimulatorHandler());
builder.addHandler(new ValidateVSpaceHandler());
builder.addHandler(new GamePermissionHandler());
builder.addHandler(new CheckStoragePermissionHandler());
builder.addHandler(new ValidateVSpaceHandler());
if (mGameEntity.getApk().size() == 1) {
builder.addHandler(new BrowserInstallHandler());

View File

@ -32,6 +32,11 @@ class CloudArchiveManagerViewModel(
) :
ListViewModel<ArchiveEntity, ArchiveEntity>(application) {
companion object {
private const val SORT_TYPE_CREATE = "time.create:-1"
private const val SORT_TYPE_SHARE_AND_CREATE = "time.share:-1,time.create:-1"
}
var archiveConfigStr = ""
private val mNewApi = RetrofitManager.getInstance().newApi
private val mApi = RetrofitManager.getInstance().api
@ -54,10 +59,10 @@ class CloudArchiveManagerViewModel(
override fun provideDataObservable(page: Int): Observable<List<ArchiveEntity>>? = when (mType) {
MyArchiveFragment.Type.MY_ARCHIVE -> {
mNewApi.getMyArchives(gameId, page)
mNewApi.getMyArchives(gameId, page, SORT_TYPE_CREATE)
}
MyArchiveFragment.Type.MY_DOWNLOAD_ARCHIVE -> null
MyArchiveFragment.Type.MY_SHARE_ARCHIVE -> mNewApi.getMyShareArchives(gameId, page)
MyArchiveFragment.Type.MY_SHARE_ARCHIVE -> mNewApi.getMyShareArchives(gameId, page, SORT_TYPE_SHARE_AND_CREATE)
}
override fun provideDataSingle(page: Int): Single<MutableList<ArchiveEntity>>? {
@ -77,7 +82,7 @@ class CloudArchiveManagerViewModel(
url = vArchiveEntity.url,
configUrl = vArchiveEntity.configUrl,
md5 = vArchiveEntity.md5,
time = ArchiveEntity.Time(update = vArchiveEntity.time),
time = ArchiveEntity.Time(create = vArchiveEntity.time),
gameVersion = vArchiveEntity.gameVersion
)
)

View File

@ -48,7 +48,7 @@ class MyArchiveAdapter(
val entity = mEntityList[position]
holder.binding.run {
titleTv.text = entity.name
timeTv.text = entity.time.update.formatTime("yyyy-MM-dd HH:mm")
timeTv.text = entity.time.create.formatTime("yyyy-MM-dd HH:mm")
versionTv.text = "版本:${entity.gameVersion}"
optionsIv.setOnClickListener {
MyArchiveOptionDialogFragment.show(

View File

@ -17,7 +17,7 @@ class MyShareArchiveFragment : MyArchiveFragment() {
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
mBinding.tipsTv.visibility = View.GONE
mBinding.reuseNoneData.reuseNoneDataTv.text = "还没有分享存档噢~"
mBinding.reuseNoneData.reuseNoneDataTv.text = "还没有分享存档噢~"
mBinding.reuseNoneData.reuseNoneDataDescTv.text = "快快把您的有趣存档分享给大家吧!"
}

View File

@ -100,9 +100,6 @@ class CommunityArticleAdapter(
}
}
if (entity.bbs == CommunityEntity()) {
entity.bbs = entity.community
}
holder.binding.selectIv.goneIf(mCurrentOption == ManageOption.OPTION_MANAGER)
holder.binding.selectIv.isChecked = selectItems.contains(entity.id)
holder.binding.imageContainer.setOffset(if (mCurrentOption == ManageOption.OPTION_MANAGER) 40f else 76f)

View File

@ -7,6 +7,9 @@ import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.activity.ToolBarActivity
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.utils.updateStatusBarColor
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.feature.exposure.ExposureSource
import java.util.ArrayList
/**
* 猜你喜欢-发现页
@ -27,9 +30,15 @@ class DiscoveryActivity : ToolBarActivity() {
}
companion object {
fun getIntent(context: Context, entrance: String): Intent {
fun getIntent(context: Context, entrance: String, exposureEvent: ExposureEvent? = null): Intent {
val bundle = Bundle()
bundle.putString(EntranceConsts.KEY_ENTRANCE, entrance)
exposureEvent?.let {
bundle.putParcelableArrayList(
EntranceConsts.KEY_EXPOSURE_SOURCE_LIST,
ArrayList(exposureEvent.source)
)
}
return getTargetIntent(context, DiscoveryActivity::class.java, DiscoveryFragment::class.java, bundle)
}
}

View File

@ -151,6 +151,8 @@ class DiscoveryFragment : LazyListFragment<DiscoveryItemData, DiscoveryViewModel
override fun provideListAdapter(): ListAdapter<*> {
val basicExposureSource = arrayListOf<ExposureSource>().apply {
arguments?.getParcelable<ExposureSource>(EntranceConsts.KEY_EXPOSURE_SOURCE)?.let { add(it) }
arguments?.getParcelableArrayList<ExposureSource>(EntranceConsts.KEY_EXPOSURE_SOURCE_LIST)
?.let { addAll(it) }
}
val outerSequence = requireArguments().getInt(EntranceConsts.KEY_POSITION, -1)

View File

@ -294,7 +294,7 @@ class GameDownloadFragmentAdapter extends BaseRecyclerAdapter<ViewHolder> {
case subscribe:
PermissionHelper.checkStoragePermissionBeforeAction(mContext, () -> {
// 下载管理不用判断是否大于50M
DialogUtils.checkDownload(mContext, Float.toString(100F), isSubscribe -> {
DialogUtils.checkDownload(mContext, Float.toString(100F), downloadEntity.getGameId(), downloadEntity.getName(), isSubscribe -> {
if (isSubscribe) {
DownloadManager.getInstance().subscribe(downloadEntity);
statusMap.put(url, DownloadStatus.subscribe.getStatus());

View File

@ -127,11 +127,12 @@ class InstalledGameViewModel(application: Application) : AndroidViewModel(applic
}
if (newEntity.getApk().size > 1) {
for (apkEntity in newEntity.getApk()) {
val packageName: String = sortedList.get(i).packageName
val packageName: String = sortedList[i].packageName
if (packageName == apkEntity.packageName) {
val list = ArrayList<ApkEntity>()
list.add(apkEntity)
newEntity.setApk(list)
newEntity.dropOtherApk()
if (PackageUtils.isCanPluggable(apkEntity)) {
val pluggableCollection =
GameUtils.getPluggableCollectionFromGameEntity(

View File

@ -19,6 +19,8 @@ import com.gh.download.DownloadManager
import com.gh.download.dialog.DownloadDialog
import com.gh.gamecenter.DownloadManagerActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.GlobalActivityManager
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.view.BugFixedPopupWindow
import com.gh.gamecenter.core.utils.CurrentActivityHolder
@ -341,7 +343,9 @@ class UpdatableGameAdapter(private var mViewModel: UpdatableGameViewModel) :
(CurrentActivityHolder.getCurrentActivity() as? FragmentActivity)?.checkStoragePermissionBeforeAction {
DialogUtils.checkDownload(
updateBtn.context,
update.size
update.size,
downloadEntity?.gameId ?: "",
downloadEntity?.name ?: ""
) { isSubscribe: Boolean ->
if (str.contains("")) {
if (update.pluggableCollection != null) {
@ -397,6 +401,21 @@ class UpdatableGameAdapter(private var mViewModel: UpdatableGameViewModel) :
updateBtn.buttonStyle = DownloadButton.ButtonStyle.NORMAL
}
}
SensorsBridge.trackEvent(
"DownLoadbuttonClick",
"game_id", update.id,
"game_name", update.name ?: "",
"game_type", update.categoryChinese,
"download_status", update.downloadStatusChinese,
"button_name", str,
"page_name", GlobalActivityManager.getCurrentPageEntity().pageName,
"page_id", GlobalActivityManager.getCurrentPageEntity().pageId,
"page_business_id", GlobalActivityManager.getCurrentPageEntity().pageBusinessId,
"last_page_name", GlobalActivityManager.getLastPageEntity().pageName,
"last_page_id", GlobalActivityManager.getLastPageEntity().pageId,
"last_page_business_id", GlobalActivityManager.getLastPageEntity().pageBusinessId
)
}
}

View File

@ -6,16 +6,17 @@ import androidx.lifecycle.*
import com.gh.common.exposure.ExposureUtils
import com.gh.common.exposure.ExposureUtils.logADownloadExposureEvent
import com.gh.common.history.HistoryHelper.insertGameEntity
import com.gh.gamecenter.feature.utils.ApkActiveUtils
import com.gh.common.util.DataCollectionUtils
import com.gh.common.util.PackageInstaller.createDownloadId
import com.gh.common.util.PackageInstaller.getDownloadPathWithId
import com.gh.common.util.PackageUtils
import com.gh.gamecenter.feature.utils.PlatformUtils
import com.gh.download.DownloadManager
import com.gh.gamecenter.common.base.BaseSimpleDao
import com.gh.gamecenter.common.base.GlobalActivityManager.getCurrentPageEntity
import com.gh.gamecenter.common.base.GlobalActivityManager.getLastPageEntity
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.retrofit.Response
import com.gh.gamecenter.common.utils.SensorsBridge.trackEvent
import com.gh.gamecenter.common.utils.addMetaExtra
import com.gh.gamecenter.common.utils.secondOrNull
import com.gh.gamecenter.common.utils.toProperReadableSize
@ -23,10 +24,12 @@ import com.gh.gamecenter.common.utils.tryCatchInRelease
import com.gh.gamecenter.core.utils.GsonUtils.toJson
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.core.utils.UrlFilterUtils
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.entity.GameUpdateEntity
import com.gh.gamecenter.feature.entity.PluginLocation
import com.gh.gamecenter.eventbus.EBDownloadChanged
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.entity.PluginLocation
import com.gh.gamecenter.feature.utils.ApkActiveUtils
import com.gh.gamecenter.feature.utils.PlatformUtils
import com.gh.gamecenter.manager.PackagesManager
import com.gh.gamecenter.retrofit.RetrofitManager
import com.halo.assistant.HaloApp
@ -586,6 +589,8 @@ class UpdatableGameViewModel(
downloadEntity.addMetaExtra(Constants.GAME_ICON_SUBSCRIPT, update.iconSubscript)
downloadEntity.addMetaExtra(Constants.DOWNLOAD_ID, downloadId)
downloadEntity.addMetaExtra(Constants.APK_MD5, update.md5)
downloadEntity.addMetaExtra(Constants.GAME_NAME, update.name)
downloadEntity.addMetaExtra(Constants.GAME_TYPE, update.categoryChinese)
if (update.iconFloat != null) {
downloadEntity.addMetaExtra(Constants.GAME_ICON_FLOAT_TOP_TEXT, update.iconFloat?.upperLeftText)
downloadEntity.addMetaExtra(Constants.GAME_ICON_FLOAT_TOP_COLOR, update.iconFloat?.upperLeftColor)
@ -634,6 +639,19 @@ class UpdatableGameViewModel(
// 收集下载数据
DataCollectionUtils.uploadDownload(getApplication(), downloadEntity, "开始")
trackEvent(
"DownloadProcessBegin",
"game_id", update.id,
"game_name", update.name ?: "",
"game_type", update.categoryChinese,
"page_name", getCurrentPageEntity().pageName,
"page_id", getCurrentPageEntity().pageId,
"page_business_id", getCurrentPageEntity().pageBusinessId,
"last_page_name", getLastPageEntity().pageName,
"last_page_id", getLastPageEntity().pageId,
"last_page_business_id", getLastPageEntity().pageBusinessId
)
}
private fun sizeStringToLong(sizeString: String): Long {

View File

@ -11,6 +11,8 @@ class AppEntity(
@SerializedName("version_code")
var versionCode: Int = 0,
var category: String? = "",
var url: String? = null,
var size: String? = null,
@ -31,6 +33,8 @@ class AppEntity(
* EVERY_TIME_OPEN每次打开
*/
var alert: String? = null,
// 关联64位更新
var relation: AppEntity? = null
) : Parcelable {
fun isAlertEveryTime() = alert == "EVERY_TIME_OPEN"

View File

@ -48,6 +48,23 @@ data class GameUpdateEntity(
var md5: String? = "",
var downloadStatus: String? = ""
) {
val categoryChinese: String
get() = when (category) {
"online" -> "网络"
"local" -> "单机"
"welfare" -> "福利"
"simulator" -> "模拟器"
else -> category ?: ""
}
val downloadStatusChinese: String
get() = when (downloadStatus) {
"on" -> "开启"
"smooth" -> "畅玩"
"appointment" -> "预约"
"demo" -> "试玩"
else -> ""
}
fun isShowPlugin(location: PluginLocation): Boolean {
if (plugin.isNullOrEmpty() || "open" == plugin || plugin == location.name) {

View File

@ -6,6 +6,8 @@ import com.gh.gamecenter.feature.entity.GameEntity
import com.google.gson.annotations.SerializedName
data class HomeSubSlide(
@SerializedName("_id")
val id: String = "",
@SerializedName("link_type")
val linkType: String = "",
@SerializedName("link_id")

View File

@ -0,0 +1,3 @@
package com.gh.gamecenter.eventbus;
public class EBAddComment {}

View File

@ -0,0 +1,3 @@
package com.gh.gamecenter.eventbus
class EBTopCommunityChanged(val communityId: String)

View File

@ -40,7 +40,7 @@ class ForumArticleAskListAdapter(
private var mDefOrderList = listOf("回复", "发布")
private var mVideoOrderList = listOf("推荐", "发布")
private var mFilterPosition = 0
private var mFilterPosition = if (path == "视频") 1 else 0
override fun areItemsTheSame(oldItem: AnswerEntity?, newItem: AnswerEntity?): Boolean {
return oldItem?.id == newItem?.id

View File

@ -21,7 +21,7 @@ class ForumArticleAskListViewModel(application: Application, val bbsId: String =
var sort: String = "time.reply"
var filter: String = "section_id"
var selectedSection = ForumDetailEntity.Section("", "全部")
var videoSort: String = "recommend"
var videoSort: String = "time.upload"
var videoList = arrayListOf<ForumVideoEntity>()
override fun provideDataObservable(page: Int): Observable<MutableList<AnswerEntity>> {

View File

@ -59,6 +59,7 @@ import com.gh.gamecenter.databinding.ItemForumSectionBinding
import com.gh.gamecenter.databinding.PopupForumDetailSectionsBinding
import com.gh.gamecenter.entity.*
import com.gh.gamecenter.eventbus.EBForumFollowChange
import com.gh.gamecenter.eventbus.EBTopCommunityChanged
import com.gh.gamecenter.eventbus.EBTypeChange
import com.gh.gamecenter.feature.entity.AnswerEntity
import com.gh.gamecenter.feature.entity.ForumVideoEntity
@ -1226,6 +1227,13 @@ class ForumDetailFragment : BaseLazyTabFragment(), IScrollable {
}
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun onTopCommunityChanged(event: EBTopCommunityChanged) {
if (event.communityId == mBbsId) {
mViewModel?.getForumDetail(true)
}
}
override fun scrollToTop() {
val fragment = mFragmentsList.safelyGetInRelease(mViewPager.currentItem)
if (fragment is IScrollable && fragment.isAdded) {

View File

@ -50,8 +50,12 @@ class ForumDetailViewModel(application: Application, val bbsId: String) : Androi
.subscribe(EmptyResponse())
}
fun getForumDetail() {
mApi.getForumDetail(bbsId)
/**
* 获取论坛详情
* @param refresh 是否刷新后台缓存
*/
fun getForumDetail(refresh: Boolean = false) {
mApi.getForumDetail(bbsId, refresh)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Response<ForumDetailEntity>() {

View File

@ -67,7 +67,7 @@ class CommunityHomeViewModel(application: Application) : AndroidViewModel(applic
articleEntity.count = articleDetailEntity.count
articleDetailEntity.community.id = articleDetailEntity.communityId
articleEntity.community = articleDetailEntity.community
articleEntity.bbs = articleDetailEntity.community
articleEntity.community = articleDetailEntity.community
articleEntity.time = articleDetailEntity.time
articleEntity.title = articleDetailEntity.title
articleEntity.user = articleDetailEntity.user
@ -89,7 +89,7 @@ class CommunityHomeViewModel(application: Application) : AndroidViewModel(applic
?: ""
articleEntity.count = questionDetailEntity.count
articleEntity.community = questionDetailEntity.community
articleEntity.bbs = questionDetailEntity.community
articleEntity.community = questionDetailEntity.community
articleEntity.time = questionDetailEntity.time
articleEntity.title = questionDetailEntity.title ?: ""
articleEntity.user = questionDetailEntity.user
@ -114,7 +114,7 @@ class CommunityHomeViewModel(application: Application) : AndroidViewModel(applic
articleEntity.length = forumVideoEntity.length
articleEntity.videoInfo = forumVideoEntity.videoInfo
articleEntity.count = forumVideoEntity.count
articleEntity.bbs = forumVideoEntity.bbs ?: CommunityEntity()
articleEntity.community = forumVideoEntity.bbs ?: CommunityEntity()
articleEntity.time = TimeEntity(upload = forumVideoEntity.time.upload)
articleEntity.title = forumVideoEntity.title
forumVideoEntity.user.run {

View File

@ -62,7 +62,6 @@ class ForumArticleListAdapter(
ItemViewType.ITEM_BODY -> {
val viewHolder = holder as ForumArticleAskItemViewHolder
val articleEntity = mEntityList[position]
articleEntity.community = CommunityEntity(articleEntity.bbs.id, articleEntity.bbs.name)
if (articleEntity.type == "bbs_article") articleEntity.type = "community_article"
if (articleEntity.type == "bbs_question") articleEntity.type = "question"
@ -102,13 +101,13 @@ class ForumArticleListAdapter(
"question" -> "提问帖"
else -> "提问帖评论"
}
val bbsType = if (bbs.type == "official_bbs") "综合论坛" else "游戏论坛"
val bbsType = if (community.type == "official_bbs") "综合论坛" else "游戏论坛"
NewLogUtils.logRecommendFeedContentClick(
"click_for_you_content",
contentType,
id,
position + 1,
bbs.id,
community.id,
bbsType,
user.id ?: ""
)

View File

@ -1264,6 +1264,8 @@ class HomeSearchToolWrapperFragment : SearchToolWrapperFragment() {
tabViewBinding.titleTv.visibility = View.GONE
tabViewBinding.invisibleTitleTv.visibility = View.GONE
tabViewBinding.titleIv.setFixedHeight(16)
// 部分设备加载图片时会获取到错误的最小宽度,这里为它做个 64DP 的保底尺寸
tabViewBinding.titleIv.setTag(ImageUtils.TAG_TARGET_WIDTH, 64F.dip2px())
tabViewBinding.titleIv.display(tabEntity.img)
tabViewBinding.titleIv.registerLoadingCallback(object : WrapContentDraweeView.LoadingCallback {
override fun loaded() {

View File

@ -136,6 +136,9 @@ class GameFragment : LazyFragment() {
arguments?.getParcelable<ExposureSource>(EntranceConsts.KEY_EXPOSURE_SOURCE)?.let {
add(it)
}
arguments?.getParcelableArrayList<ExposureSource>(EntranceConsts.KEY_EXPOSURE_SOURCE_LIST)?.let {
addAll(it)
}
add(
ExposureSource(
"板块",

View File

@ -14,7 +14,8 @@ class CommonCollectionDetailActivity : ToolBarActivity() {
return getTargetIntent(
this,
CommonCollectionDetailActivity::class.java,
CommonCollectionDetailFragment::class.java
CommonCollectionDetailFragment::class.java,
intent?.extras
)
}

View File

@ -28,7 +28,8 @@ class CommonCollectionDetailAdapter(
val mViewModel: CommonCollectionDetailViewModel,
val mBlockId: String,
val mBlockName: String,
val mEntrance: String
val mEntrance: String,
private val mBasicExposureSource: List<ExposureSource>?
) : ListAdapter<CommonCollectionContentEntity>(context), IExposable {
private val mExposureEventSparseArray = SparseArray<ExposureEvent>()
@ -98,13 +99,14 @@ class CommonCollectionDetailAdapter(
if (linkEntity.type == "game") {
mExposureEventSparseArray.put(
position,
ExposureEvent.createEvent(
ExposureEvent.createEventWithSourceConcat(
GameEntity(
id = linkEntity.link,
name = linkEntity.name
).also {
it.sequence = position
},
basicSource = mBasicExposureSource ?: listOf(),
listOf(
ExposureSource(
"内容合集",

View File

@ -21,6 +21,7 @@ import com.gh.gamecenter.common.view.GridSpacingItemDecoration
import com.gh.gamecenter.common.view.VerticalItemDecoration
import com.gh.gamecenter.databinding.FragmentListBaseSkeletonBinding
import com.gh.gamecenter.common.entity.LinkEntity
import com.gh.gamecenter.feature.exposure.ExposureSource
class CommonCollectionDetailFragment : LazyListFragment<LinkEntity, CommonCollectionDetailViewModel>() {
@ -47,13 +48,16 @@ class CommonCollectionDetailFragment : LazyListFragment<LinkEntity, CommonCollec
override fun provideListAdapter(): ListAdapter<*> {
if (mAdapter == null) {
val exposureEvent =
requireArguments().getParcelableArrayList<ExposureSource>(EntranceConsts.KEY_EXPOSURE_SOURCE_LIST)
mAdapter = CommonCollectionDetailAdapter(
requireContext(),
mCollectionStyle,
mViewModel,
mBlockId,
mBlockName,
mEntrance
mEntrance,
exposureEvent
)
}
return mAdapter!!

View File

@ -59,14 +59,34 @@ class GameGallerySlideViewHolder(val binding: GameGallerySlideItemBinding) : Bas
binding.cardView.setCardBackgroundColor(R.color.text_FAFAFA.toColor(binding.root.context))
}
/**
* 获取分割好的游戏列表数据
*/
private fun getDividedGameList(): ArrayList<ArrayList<GameEntity>> {
val containerList = arrayListOf<ArrayList<GameEntity>>()
val gameDataList = mCachedSubject!!.data!!
val gameListSize = gameDataList.size
val bestNumber = mCachedSubject!!.data!!.size / 3
// 分割大小
val splitSize = gameDataList.size / 3
containerList.add(ArrayList(mCachedSubject!!.data!!.subList(0, bestNumber - 1)))
containerList.add(ArrayList(mCachedSubject!!.data!!.subList(bestNumber, bestNumber * 2 - 1)))
containerList.add(ArrayList(mCachedSubject!!.data!!.subList(bestNumber * 2, mCachedSubject!!.data!!.size - 1)))
if (splitSize > 1) {
containerList.add(ArrayList(gameDataList.subList(0, splitSize)))
containerList.add(ArrayList(gameDataList.subList(splitSize, splitSize * 2)))
containerList.add(ArrayList(gameDataList.subList(splitSize * 2, gameListSize)))
} else if (splitSize == 1) {
containerList.add(ArrayList(gameDataList.subList(0, 1)))
containerList.add(ArrayList(gameDataList.subList(1, 2)))
containerList.add(ArrayList(gameDataList.subList(2, 3)))
} else {
val tempGameList = arrayListOf<GameEntity>()
if (gameListSize != 0) {
tempGameList.add(gameDataList.first())
}
containerList.add(tempGameList)
containerList.add(tempGameList)
containerList.add(tempGameList)
}
return containerList
}
@ -88,6 +108,8 @@ class GameGallerySlideViewHolder(val binding: GameGallerySlideItemBinding) : Bas
}
override fun onBindViewHolder(holder: GameGallerySlideItemViewHolder, position: Int) {
if (gameList.isEmpty()) return
val gameEntity = gameList[position % gameList.size]
runOnIoThread(true) {

View File

@ -62,12 +62,13 @@ class GameVerticalAdapter(
// 你可能会问为什么这下面会有一些,"加1减1" 的魔法。没错,这里的 "加1减1"就是为了规避 bug做出的一些 UI 补偿
// bug 的表现可以 checkout https://git.shanqu.cc/android/playground/-/tree/test-snap_adapter_culprit 代码,然后滑动到最后一列体验一下
var paddingEnd = if (isEndOfRow) 16F.dip2px() else 0F.dip2px()
val height = 80F.dip2px()
holder.itemView.layoutParams = if (!isEndOfRow) {
paddingEnd += 1
ViewGroup.LayoutParams(mMaxWidth - 24F.dip2px(), ViewGroup.LayoutParams.WRAP_CONTENT)
ViewGroup.LayoutParams(mMaxWidth - 24F.dip2px(), height)
} else {
ViewGroup.LayoutParams(mMaxWidth - 1, ViewGroup.LayoutParams.WRAP_CONTENT)
ViewGroup.LayoutParams(mMaxWidth - 1, height)
}
val gameEntity = mSubjectEntity.data!![position + getIndex()]
@ -158,18 +159,19 @@ class GameVerticalAdapter(
fun checkResetData(updateData: SubjectEntity) {
var dataIds = ""
mSubjectEntity = updateData
mSubjectEntity.data?.forEach {
dataIds += it.id
}
mSubjectEntity = updateData
if ((countAndKey?.first == updateData.data?.size && countAndKey?.second != dataIds) || mDarkMode != DarkModeUtils.isDarkModeOn(
mContext
)
) { // 数量不变,内容发生改变
if ((countAndKey?.first == updateData.data?.size && countAndKey?.second != dataIds)
|| mDarkMode != DarkModeUtils.isDarkModeOn(mContext)
) {
// 数量不变,内容发生改变
notifyItemRangeChanged(0, itemCount)
mDarkMode = DarkModeUtils.isDarkModeOn(mContext)
} else if (countAndKey?.first != updateData.data?.size) { // 数量发生改变
} else if (countAndKey?.first != updateData.data?.size) {
// 数量发生改变
notifyDataSetChanged()
}

View File

@ -56,8 +56,8 @@ class CloudArchiveListViewModel(
private fun getSortTypeFilter(): String {
return when (mSortType) {
SortType.NEWEST -> "time.create:-1"
else -> "hot:-1"
SortType.NEWEST -> "time.share:-1"
else -> "count.usage:-1,time.share:-1"
}
}

View File

@ -60,11 +60,11 @@ class GameLibaoAdapter(
when (holder) {
is LibaoViewHolder -> {
val libaoEntity = libaos[position]
val isTypeCopy = libaoEntity.receiveMethod == "copy"
holder.binding.libaoNameTv.text = libaoEntity.name
holder.binding.contentTv.text = libaoEntity.content?.fromHtml()
val isTypeCopy = libaoEntity.receiveMethod == "copy"
if (isTypeCopy) {
// 类型为复制,不需要登录也能直接领取
holder.binding.libaoSchedulePb.visibility = View.GONE
@ -93,10 +93,7 @@ class GameLibaoAdapter(
holder.binding.libaoCodeTv.text = "礼包码:-"
} else {
when (libaoEntity.status) {
"ling" -> {
holder.binding.libaoCodeTv.text = "礼包码:-"
}
"linged", "repeatLing", "repeatLinged" -> {
"linged", "repeatLing", "repeatLinged", "taoed", "repeatTao", "repeatTaoed" -> {
val size = libaoEntity.me?.userDataLibaoList?.size ?: 0
val code = libaoEntity.me?.userDataLibaoList?.get(size - 1)?.code ?: ""
val text = "礼包码:$code"
@ -125,14 +122,7 @@ class GameLibaoAdapter(
initProgressUI(libaoEntity, holder)
} else {
when (libaoEntity.status) {
"ling" -> {
holder.binding.libaoSchedulePb.visibility = View.VISIBLE
holder.binding.remainingTv.visibility = View.VISIBLE
holder.binding.libaoCodeTv.visibility = View.GONE
initProgressUI(libaoEntity, holder)
}
"linged", "repeatLing", "repeatLinged" -> {
"linged", "repeatLing", "repeatLinged", "taoed", "repeatTao", "repeatTaoed" -> {
holder.binding.libaoSchedulePb.visibility = View.GONE
holder.binding.remainingTv.visibility = View.GONE
holder.binding.libaoCodeTv.visibility = View.VISIBLE
@ -152,10 +142,11 @@ class GameLibaoAdapter(
}
}
else -> {
holder.binding.libaoSchedulePb.visibility = View.GONE
holder.binding.remainingTv.visibility = View.GONE
holder.binding.libaoCodeTv.visibility = View.VISIBLE
holder.binding.libaoCodeTv.text = "礼包码:-"
holder.binding.libaoSchedulePb.visibility = View.VISIBLE
holder.binding.remainingTv.visibility = View.VISIBLE
holder.binding.libaoCodeTv.visibility = View.GONE
initProgressUI(libaoEntity, holder)
}
}
}

View File

@ -1,9 +1,12 @@
package com.gh.gamecenter.geetest;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.os.Build;
import com.gh.gamecenter.core.AppExecutor;
import com.gh.gamecenter.core.utils.AppDebugConfig;
import com.gh.gamecenter.common.retrofit.JSONObjectResponse;
import com.gh.gamecenter.retrofit.RetrofitManager;
@ -113,6 +116,10 @@ public class GeetestUtils {
mRetryCount = 0;
final GtDialog dialog = new GtDialog(context, params);
if (context instanceof Activity) {
dialog.setOwnerActivity((Activity) context);
}
// 启用debug可以在webview上看到验证过程的一些数据
dialog.setDebug(AppDebugConfig.IS_DEBUG);
@ -128,85 +135,88 @@ public class GeetestUtils {
@Override
public void gtCallReady(Boolean status) {
if (AppDebugConfig.IS_DEBUG) {
AppDebugConfig.logMethodWithParams(this, status, mProgressDialog.isShowing());
}
AppExecutor.getUiExecutor().execute(() -> {
if (AppDebugConfig.IS_DEBUG) {
AppDebugConfig.logMethodWithParams(this, status, mProgressDialog.isShowing());
}
mRetryCount = 0;
if (!mProgressDialog.isShowing()) {
//被手动取消了也就是其实用户想取消loading了那么即使回调也不弹出
return;
}
mRetryCount = 0;
if (!mProgressDialog.isShowing()) {
//被手动取消了也就是其实用户想取消loading了那么即使回调也不弹出
return;
}
mProgressDialog.dismiss();
mProgressDialog.dismiss();
if (status) {
// 验证加载完成
RuntimeUtils.getInstance().runOnUiThread(new Runnable() {
if (status) {
// 验证加载完成
Activity ownerActivity = dialog.getOwnerActivity();
@Override
public void run() {
if (dialog != null) {
dialog.show();
}
if (ownerActivity != null
&& (ownerActivity.isFinishing()
|| (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR1) && ownerActivity.isDestroyed())) {
// activity 不可见
toastMsg(context, "验证加载超时,请重新尝试");
} else {
dialog.show();
}
});
} else {
// 验证加载超时,未准备完成
toastMsg(context, "验证加载超时,请重新尝试");
}
} else {
// 验证加载超时,未准备完成
toastMsg(context, "验证加载超时,请重新尝试");
}
});
}
@Override
public void gtCallClose() {
if (AppDebugConfig.IS_DEBUG) {
AppDebugConfig.logMethodWithParams(this);
}
if (dialog != null && dialog.isShowing()) {
dialog.dismiss();
}
// toastMsg("close geetest windows");
AppExecutor.getUiExecutor().execute(() -> {
if (AppDebugConfig.IS_DEBUG) {
AppDebugConfig.logMethodWithParams(this);
}
if (dialog != null && dialog.isShowing()) {
dialog.dismiss();
}
});
}
@Override
public void gtError() {
if (AppDebugConfig.IS_DEBUG) {
AppDebugConfig.logMethodWithParams(this);
}
if (mRetryCount < RETRY_MAX_COUNT) {
mRetryCount++;
checkServer(context);
} else {
if (mProgressDialog.isShowing()) {
mProgressDialog.dismiss();
AppExecutor.getUiExecutor().execute(() -> {
if (AppDebugConfig.IS_DEBUG) {
AppDebugConfig.logMethodWithParams(this);
}
}
if (mRetryCount < RETRY_MAX_COUNT) {
mRetryCount++;
checkServer(context);
} else {
if (mProgressDialog.isShowing()) {
mProgressDialog.dismiss();
}
}
});
}
@Override
public void gtResult(boolean success, String result) {
if (AppDebugConfig.IS_DEBUG) {
AppDebugConfig.logMethodWithParams(this, success, result);
}
if (success) {
if (dialog != null && dialog.isShowing()) {
dialog.dismiss();
AppExecutor.getUiExecutor().execute(() -> {
if (AppDebugConfig.IS_DEBUG) {
AppDebugConfig.logMethodWithParams(this, success, result);
}
if (mGeetestListener != null) {
mGeetestListener.onVerified(result);
}
// toastMsg("client captcha succeed:" + result);
Utils.log("client captcha succeed:" + result);
} else {
// 验证失败
// toastMsg("client captcha failed:" + result);
Utils.log("client captcha failed:" + result);
}
if (success) {
if (dialog != null && dialog.isShowing()) {
dialog.dismiss();
}
if (mGeetestListener != null) {
mGeetestListener.onVerified(result);
}
Utils.log("client captcha succeed:" + result);
} else {
// 验证失败
Utils.log("client captcha failed:" + result);
}
});
}
});
@ -218,7 +228,6 @@ public class GeetestUtils {
if (AppDebugConfig.IS_DEBUG) {
AppDebugConfig.logMethodWithParams(this);
}
}
});

View File

@ -67,6 +67,7 @@ class HomeGameCollectionAdapter(
val gamesCollectionEntity = itemData.gameCollectionItem
root.layoutParams.width = DisplayUtils.getScreenWidth() - 50F.dip2px()
if (gamesCollectionEntity != null) {
poster.setTag(ImageUtils.TAG_TARGET_WIDTH, DisplayUtils.getScreenWidth() - 50F.dip2px())
ImageUtils.display(poster, gamesCollectionEntity.cover)
ImageUtils.display(userIv, gamesCollectionEntity.user?.icon)
titleTv.text = gamesCollectionEntity.title

View File

@ -4,7 +4,6 @@ import android.graphics.Typeface
import android.graphics.drawable.GradientDrawable
import android.view.MotionEvent
import android.view.View
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
import androidx.core.graphics.ColorUtils
import androidx.core.view.isVisible
@ -34,7 +33,6 @@ import com.gh.gamecenter.feature.exposure.ExposureSource
import com.gh.gamecenter.feature.exposure.ExposureType
import com.gh.gamecenter.home.HomeItemData
import com.gh.gamecenter.home.HomeViewModel
import splitties.views.dsl.core.endMargin
import kotlin.math.abs
class HomeSlideWithCardsViewHolder(
@ -257,11 +255,10 @@ class HomeSlideWithCardsViewHolder(
source = listOf(
ExposureSource(
"右侧卡片",
"${homeSubSlide.cardId} - ${getCardTypeChinese(homeSubSlide.cardType)}"
"${homeSubSlide.id} - ${getCardTypeChinese(homeSubSlide.cardType)}"
)
)
)
itemData.exposureEventList?.add(exposureEvent)
when (homeSubSlide.cardType) {
"column",
@ -285,6 +282,14 @@ class HomeSlideWithCardsViewHolder(
gameIconStackIv1.visibility = View.GONE
}
homeSubSlide.cardData.games.take(3).forEachIndexed { index, gameEntity ->
itemData.exposureEventList?.add(
getGameExposureEvent(
homeSubSlide,
gameEntity,
position,
basicExposureSource
)
)
when (index) {
0 -> gameIconStackIv3.displayGameIcon(gameEntity, true)
1 -> gameIconStackIv2.displayGameIcon(gameEntity, true)
@ -314,6 +319,17 @@ class HomeSlideWithCardsViewHolder(
gameIconIv3.visibility = View.GONE
}
homeSubSlide.cardData.games.take(3).forEachIndexed { index, gameEntity ->
val gameExposureEvent =
getGameExposureEvent(homeSubSlide, gameEntity, position, basicExposureSource)
itemData.exposureEventList?.add(
getGameExposureEvent(
homeSubSlide,
gameEntity,
position,
basicExposureSource
)
)
when (index) {
0 -> {
gameIconIv1.displayGameIcon(gameEntity, true)
@ -327,10 +343,11 @@ class HomeSlideWithCardsViewHolder(
binding.root.context,
gameEntity.id,
BaseActivity.mergeEntranceAndPath("新首页", "右侧卡片"),
exposureEvent
gameExposureEvent
)
}
}
1 -> {
gameIconIv2.displayGameIcon(gameEntity, true)
gameIconIv2.setOnClickListener {
@ -343,10 +360,11 @@ class HomeSlideWithCardsViewHolder(
binding.root.context,
gameEntity.id,
BaseActivity.mergeEntranceAndPath("新首页", "右侧卡片"),
exposureEvent
gameExposureEvent
)
}
}
2 -> {
gameIconIv3.displayGameIcon(gameEntity, true)
gameIconIv3.setOnClickListener {
@ -359,7 +377,7 @@ class HomeSlideWithCardsViewHolder(
binding.root.context,
gameEntity.id,
BaseActivity.mergeEntranceAndPath("新首页", "右侧卡片"),
exposureEvent
gameExposureEvent
)
}
}
@ -417,6 +435,8 @@ class HomeSlideWithCardsViewHolder(
connect(textContainer.id, ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.TOP)
connect(textContainer.id, ConstraintSet.BOTTOM, ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM)
}.applyTo(cardContainer)
itemData.exposureEventList?.add(exposureEvent)
}
}
@ -431,17 +451,42 @@ class HomeSlideWithCardsViewHolder(
source = listOf(
ExposureSource(
"右侧卡片",
"${homeSubSlide.cardId} - ${getCardTypeChinese(homeSubSlide.cardType)}"
"${homeSubSlide.id} - ${getCardTypeChinese(homeSubSlide.cardType)}"
)
),
event = ExposureType.CLICK
)
)
com.gh.common.util.NewFlatLogUtils.logRightSideCardClick(homeSubSlide, viewModel.refreshCount, "卡片")
DirectUtils.directToLinkPage(cardCv.context, homeSubSlide.toLinkEntity(), "新首页", "右侧卡片", exposureEvent)
DirectUtils.directToLinkPage(
cardCv.context,
homeSubSlide.toLinkEntity(),
"新首页",
"右侧卡片",
exposureEvent
)
}
}
private fun getGameExposureEvent(
homeSubSlide: HomeSubSlide,
gameEntity: GameEntity,
position: Int,
basicExposureSource: List<ExposureSource>
) = ExposureEvent.createEventWithSourceConcat(
gameEntity = gameEntity.apply {
sequence = position
outerSequence = viewModel.refreshCount
},
basicSource = basicExposureSource,
source = listOf(
ExposureSource(
"右侧卡片",
"${homeSubSlide.id} - ${getCardTypeChinese(homeSubSlide.cardType)}"
)
)
)
private fun updateImmersiveColor(color: Int) {
callback.invoke(color)
val gradientDrawable = DrawableView.getGradientDrawable(

View File

@ -127,7 +127,12 @@ class HomeItemGameTestV2ViewHolder(
super.onScrollStateChanged(recyclerView, newState)
Utils.log("onScrollStateChanged: newState = $newState")
if (newState == RecyclerView.SCROLL_STATE_IDLE) {
recyclerView.handler.removeCallbacksAndMessages(null)
// 高速滑动时可能触发空指针闪退
try {
recyclerView.handler.removeCallbacksAndMessages(null)
} catch (e: NullPointerException) {
e.printStackTrace()
}
recyclerView.postDelayed(300) { // 解决动画没结束时候条目和时间轴不对应问题
onRecyclerViewChanged(true)
}

View File

@ -263,7 +263,7 @@ class ConcernAdapter extends BaseRecyclerAdapter<ViewHolder> {
}
// 获取新闻评论数
private void getNewsCommentnum(final List<ConcernEntity> list) {
public void getNewsCommentnum(final List<ConcernEntity> list) {
if (list == null || list.isEmpty()) {
return;
}
@ -508,6 +508,10 @@ class ConcernAdapter extends BaseRecyclerAdapter<ViewHolder> {
return null;
}
public List<ConcernEntity> getConcernList() {
return concernList;
}
public List<LibaoStatusEntity> getLibaoStatusList() {
return libaoStatusList;
}

View File

@ -20,6 +20,8 @@ import androidx.swiperefreshlayout.widget.SwipeRefreshLayout;
import com.gh.gamecenter.common.callback.OnRequestCallBackListener;
import com.gh.gamecenter.common.base.activity.ToolBarActivity;
import com.gh.common.filter.RegionSettingHelper;
import com.gh.gamecenter.eventbus.EBAddComment;
import com.gh.gamecenter.eventbus.EBDeleteComment;
import com.gh.gamecenter.feature.utils.ApkActiveUtils;
import com.gh.common.util.CheckLoginUtils;
import com.gh.common.util.DataCollectionUtils;
@ -386,6 +388,16 @@ public class ConcernFragment extends ToolbarFragment implements SwipeRefreshLayo
}
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onAddComment(EBAddComment event) {
mAdapter.getNewsCommentnum(mAdapter.getConcernList());
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onDeleteComment(EBDeleteComment event) {
mAdapter.getNewsCommentnum(mAdapter.getConcernList());
}
@Override
public void onRefresh() {
postDelayedRunnable(mRunnable, 1000);

View File

@ -44,24 +44,32 @@ import com.gh.gamecenter.entity.CommentEntity;
import com.gh.gamecenter.entity.CommentnumEntity;
import com.gh.gamecenter.entity.ConcernEntity;
import com.gh.gamecenter.entity.ViewsEntity;
import com.gh.gamecenter.eventbus.EBAddComment;
import com.gh.gamecenter.eventbus.EBDeleteComment;
import com.gh.gamecenter.login.entity.UserInfoEntity;
import com.gh.gamecenter.login.user.UserManager;
import com.gh.gamecenter.manager.CommentManager;
import com.gh.gamecenter.retrofit.RetrofitManager;
import com.gh.gamecenter.retrofit.service.ApiService;
import com.halo.assistant.HaloApp;
import com.lightgame.listeners.OnBackPressedListener;
import com.lightgame.utils.Util_System_Keyboard;
import com.lightgame.utils.Utils;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.Arrays;
import java.util.List;
import java.util.function.BiFunction;
import io.reactivex.Observable;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.functions.Function3;
import io.reactivex.schedulers.Schedulers;
import retrofit2.HttpException;
@ -199,46 +207,34 @@ public class MessageDetailFragment extends ToolbarFragment implements OnCommentC
mBinding.shadowView.setOnClickListener(this);
}
public void getCommentNum() {
RetrofitManager.getInstance().getApi()
.getNewsCommentnum(newsId, Utils.getTime(getContext()))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Response<List<CommentnumEntity>>() {
@Override
public void onResponse(List<CommentnumEntity> response) {
super.onResponse(response);
if (response.size() > 0) {
if (!TextUtils.isEmpty(mConcernEntity.getId())) {
commentNum = response.get(0).getNum();
mConcernEntity.setCommentnum(commentNum);
adapter.notifyItemChanged(0);
}
private void getConcernDigest() {
ApiService apiService = RetrofitManager.getInstance().getApi();
Observable.zip(
apiService.getNewsRichDigest(newsId),
apiService.getArticlesVisits(UrlFilterUtils.getFilterQuery("article_ids", newsId)),
apiService.getNewsCommentnum(newsId, Utils.getTime(getContext())),
(concernEntity, viewsEntities, commentNumEntities) -> {
if (commentNumEntities.size() > 0) {
if (!TextUtils.isEmpty(concernEntity.getId())) {
concernEntity.setCommentnum(commentNumEntities.get(0).getNum());
}
}
});
}
private void getConcernDigest() {
RetrofitManager.getInstance().getApi().getNewsRichDigest(newsId)
if (viewsEntities.size() > 0) {
concernEntity.setViews(viewsEntities.get(0).getViews());
}
return concernEntity;
})
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Response<ConcernEntity>() {
@Override
public void onResponse(ConcernEntity response) {
mConcernEntity = response;
if (commentNum == -1) {
getCommentNum();
} else {
mConcernEntity.setCommentnum(commentNum);
}
commentNum = mConcernEntity.getCommentnum();
adapter.addConcernEntity(mConcernEntity);
adapter.notifyDataSetChanged();
adapter.addHotComment();
getNewsViews();
if (commentNum == 0) {
setSoftInput(true);
}
@ -251,22 +247,6 @@ public class MessageDetailFragment extends ToolbarFragment implements OnCommentC
});
}
private void getNewsViews() {
RetrofitManager.getInstance().getApi()
.getArticlesVisits(UrlFilterUtils.getFilterQuery("article_ids", newsId))
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Response<List<ViewsEntity>>() {
@Override
public void onResponse(List<ViewsEntity> viewsEntities) {
if (viewsEntities.size() > 0) {
mConcernEntity.setViews(viewsEntities.get(0).getViews());
adapter.notifyItemChanged(0);
}
}
});
}
//软键盘控制
private void setSoftInput(boolean isShow) {
if (isShow) {
@ -297,6 +277,17 @@ public class MessageDetailFragment extends ToolbarFragment implements OnCommentC
}
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onDeleteComment(EBDeleteComment event) {
adapter.notifyCommentRemoved(event.commentEntity);
}
@Subscribe(threadMode = ThreadMode.MAIN)
public void onAddComment(EBAddComment event) {
commentNum = -1;
getConcernDigest();
}
@Override
public void onClick(View view) {
switch (view.getId()) {
@ -375,6 +366,8 @@ public class MessageDetailFragment extends ToolbarFragment implements OnCommentC
//修改评论缓存
CommentManager.updateOkhttpCacheForId(getContext(), newsId);
CommentManager.updateOkhttpCache(getContext(), newsId);
// 发送评论更新通知
EventBus.getDefault().post(new EBAddComment());
adapter.notifyItemInserted(adapter.getHotCommentListSize() + 2);
adapter.notifyItemChanged(adapter.getItemCount() - 1); //刷新脚布局高度
} else {

View File

@ -64,6 +64,7 @@ import com.gh.gamecenter.databinding.GamedetailItemNewsBinding;
import com.gh.gamecenter.databinding.NewsDetailCommentBinding;
import com.gh.gamecenter.databinding.NewsdetailItemContentBinding;
import com.gh.gamecenter.databinding.NewsdetailItemGameBinding;
import com.gh.gamecenter.eventbus.EBDeleteComment;
import com.gh.gamecenter.feature.entity.ApkEntity;
import com.gh.gamecenter.entity.ArticleCommentParent;
import com.gh.gamecenter.feature.entity.ColorEntity;
@ -77,9 +78,12 @@ import com.gh.gamecenter.retrofit.RetrofitManager;
import com.lightgame.adapter.BaseRecyclerAdapter;
import com.lightgame.utils.Utils;
import org.greenrobot.eventbus.EventBus;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicBoolean;
import io.reactivex.android.schedulers.AndroidSchedulers;
@ -579,8 +583,16 @@ public class NewsDetailAdapter extends BaseRecyclerAdapter<ViewHolder> {
return true;
});
viewHolder.commentMore.setOnClickListener(v ->
CommentUtils.showReportDialog(commentEntity,
mContext, true, "资讯文章详情-评论"));
CommentUtils.showMorePopupWindow(
viewHolder.commentMore,
commentEntity,
true,
"资讯文章详情-评论",
() -> {
EventBus.getDefault().post(new EBDeleteComment(commentEntity));
}
)
);
viewHolder.commentUserNameTv.setOnClickListener(v -> DirectUtils.directToHomeActivity(mContext, commentEntity.getUser().getId(), mEntrance, "文章-评论列表"));
viewHolder.commentUserIconDv.setOnClickListener(v -> DirectUtils.directToHomeActivity(mContext, commentEntity.getUser().getId(), mEntrance, "文章-评论列表"));
@ -679,10 +691,8 @@ public class NewsDetailAdapter extends BaseRecyclerAdapter<ViewHolder> {
@Override
public void onResponse(List<CommentnumEntity> response) {
if (response.size() > 0 && response.get(0).getNum() > 0) {
mCommentNum = response.get(0).getNum();
getNewsHotComment();
}
mCommentNum = response.get(0).getNum();
getNewsHotComment();
}
@Override
@ -726,9 +736,9 @@ public class NewsDetailAdapter extends BaseRecyclerAdapter<ViewHolder> {
public void onResponse(List<CommentEntity> response) {
if (response.size() >= 1) {
mIsHotComment = false;
mCommentEntityList = response;
notifyDataSetChanged();
}
mCommentEntityList = response;
notifyDataSetChanged();
}
});
}

View File

@ -0,0 +1,22 @@
package com.gh.gamecenter.oaid
import android.content.Context
import com.alibaba.android.arouter.launcher.ARouter
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.core.provider.IOAIDProvider
object OAIDHelper {
fun doSystemLoad() {
val oaidProvider = ARouter.getInstance().build(RouteConsts.provider.oaid).navigation() as? IOAIDProvider
oaidProvider?.doSystemLoad()
}
fun getOAID(context: Context, callback: (String) -> Unit) {
val oaidProvider = ARouter.getInstance().build(RouteConsts.provider.oaid).navigation() as? IOAIDProvider
oaidProvider?.getOAID(context, callback)
}
}

View File

@ -132,13 +132,13 @@ open class BaseAnswerOrArticleItemViewHolder(itemView: View) : BaseRecyclerViewH
open fun bindCommendAndVote(entity: ArticleEntity, entrance: String, position: Int? = null) {
binNormalView(entity.transformAnswerEntity())
if (entity.bbs.type == "official_bbs") {
forumIcon?.displayGameIcon(entity.bbs.icon, null)
if (entity.community.type == "official_bbs") {
forumIcon?.displayGameIcon(entity.community.icon, null)
} else {
forumIcon?.displayGameIcon(
entity.bbs.game?.getIcon(),
entity.bbs.game?.iconSubscript,
entity.bbs.game?.iconFloat
entity.community.game?.getIcon(),
entity.community.game?.iconSubscript,
entity.community.game?.iconFloat
)
}
@ -148,17 +148,17 @@ open class BaseAnswerOrArticleItemViewHolder(itemView: View) : BaseRecyclerViewH
"question" -> "提问帖"
else -> "提问帖评论"
}
val bbsType = if (entity.bbs.type == "official_bbs") "综合论坛" else "游戏论坛"
val bbsType = if (entity.community.type == "official_bbs") "综合论坛" else "游戏论坛"
forumNameTv.setOnClickListener {
if (entrance == "社区+(推荐)") {
NewLogUtils.logRecommendFeedForumClick(contentType, entity.id, entity.bbs.id, bbsType)
NewLogUtils.logRecommendFeedForumClick(contentType, entity.id, entity.community.id, bbsType)
}
MtaHelper.onEvent(
getEventId(entrance),
getKey(entrance),
if (entity.bbs.name.isEmpty()) entity.community.name else entity.bbs.name
if (entity.community.name.isEmpty()) entity.community.name else entity.community.name
)
itemView.context.startActivity(
ForumDetailActivity.getIntent(
@ -207,7 +207,7 @@ open class BaseAnswerOrArticleItemViewHolder(itemView: View) : BaseRecyclerViewH
contentType,
id,
(position + 1),
bbs.id,
community.id,
bbsType,
user.id ?: "",
commentType
@ -266,7 +266,7 @@ open class BaseAnswerOrArticleItemViewHolder(itemView: View) : BaseRecyclerViewH
contentType,
id,
position + 1,
bbs.id,
community.id,
bbsType,
user.id ?: ""
)

View File

@ -70,7 +70,7 @@ class MyArticleAdapter(
mContext.startActivity(
ArticleDetailActivity.getIntent(
mContext,
entity.bbs,
entity.community,
entity.id,
mEntrance,
mPath

View File

@ -38,6 +38,7 @@ import com.gh.gamecenter.databinding.FragmentArticleDetailBinding
import com.gh.gamecenter.entity.*
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.Permissions
import com.gh.gamecenter.login.user.UserManager
@ -453,6 +454,22 @@ class ArticleDetailFragment : BaseCommentFragment<CommentItemData, ArticleDetail
}
}
mViewModel.top.observeNonNull(this) { top ->
val topSuccessToast = if(top) {
R.string.article_detail_top_success_toast
} else {
R.string.article_detail_cancel_top_success_toast
}
toast(getString(topSuccessToast))
mViewModel.detailEntity?.let {
EventBus.getDefault().post(
EBTopCommunityChanged(
it.communityId
)
)
}
}
mViewModel.dislike.observeNonNull(this) { disliked ->
if (disliked) {
toast("已反对")
@ -508,58 +525,82 @@ class ArticleDetailFragment : BaseCommentFragment<CommentItemData, ArticleDetail
private fun showMoreItemDialog() {
if (lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED) || mViewModel.detailEntity != null) {
val entities = ArrayList<MenuItemEntity>()
// 申请加精
if (mViewModel.detailEntity?.user?.id == UserManager.getInstance().userId && !mViewModel.detailEntity?.me!!.isModerator && mViewModel.detailEntity?.status == "pass") {
val isEnable =
mViewModel.detailEntity?.getSimplifyChoicenessStatus() != "pass"
mViewModel.detailEntity?.getSimplifyChoicenessStatus() != ArticleDetailEntity.STATUS_PASS
entities.add(
MenuItemEntity(
"申请加精",
getString(R.string.article_detail_more_apply_select_title),
if (isEnable)
R.drawable.icon_more_panel_essence else R.drawable.icon_more_panel_essence_unenable,
isEnable = isEnable
)
)
}
if (mViewModel.detailEntity?.user?.id == UserManager.getInstance().userId && mViewModel.detailEntity?.status == "pass") {
entities.add(MenuItemEntity("修改", R.drawable.icon_more_panel_edit))
// 修改
if (mViewModel.detailEntity?.user?.id == UserManager.getInstance().userId
&& mViewModel.detailEntity?.status == ArticleDetailEntity.STATUS_PASS) {
entities.add(MenuItemEntity(getString(R.string.article_detail_more_edit_title), R.drawable.icon_more_panel_edit))
}
// 举报
if (mViewModel.detailEntity?.user?.id != UserManager.getInstance().userId) {
entities.add(MenuItemEntity("投诉", R.drawable.icon_gamedetail_copyright))
entities.add(MenuItemEntity(getString(R.string.article_detail_more_complaint_title), R.drawable.icon_gamedetail_copyright))
}
val moderatorPermissions = mViewModel.detailEntity?.me?.moderatorPermissions
if (mViewModel.detailEntity?.me?.isModerator == true && mViewModel.detailEntity?.status == "pass") {
if (mViewModel.detailEntity?.getSimplifyChoicenessStatus() == "pass") {
// 取消精选
if (mViewModel.detailEntity?.me?.isModerator == true
&& mViewModel.detailEntity?.status == ArticleDetailEntity.STATUS_PASS) {
if (mViewModel.detailEntity?.getSimplifyChoicenessStatus() == ArticleDetailEntity.STATUS_PASS) {
if ((moderatorPermissions?.cancelHighlightCommunityArticle
?: Permissions.GUEST) > Permissions.GUEST
) {
entities.add(MenuItemEntity("取消精选", R.drawable.icon_more_panel_essence_cancel))
entities.add(MenuItemEntity(getString(R.string.article_detail_more_unselect_title), R.drawable.icon_more_panel_essence_cancel))
}
} else {
if ((moderatorPermissions?.highlightCommunityArticle
?: Permissions.GUEST) > Permissions.GUEST
) {
entities.add(MenuItemEntity("加精选", R.drawable.icon_more_panel_essence))
entities.add(MenuItemEntity(getString(R.string.article_detail_more_select_title), R.drawable.icon_more_panel_essence))
}
}
}
// 修改活动标签
if (mViewModel.detailEntity?.me?.isModerator == true &&
(moderatorPermissions?.updateArticleActivityTag
?: Permissions.GUEST) > Permissions.GUEST &&
mViewModel.detailEntity?.status == "pass"
mViewModel.detailEntity?.status == ArticleDetailEntity.STATUS_PASS
) {
entities.add(MenuItemEntity("修改活动标签", R.drawable.icon_more_panel_modify_label))
entities.add(MenuItemEntity(getString(R.string.article_detail_more_edit_activity_tag_title), R.drawable.icon_more_panel_modify_label))
}
// 隐藏/删除
if (mViewModel.detailEntity?.me?.isModerator == true &&
(moderatorPermissions?.hideCommunityArticle
?: Permissions.GUEST) > Permissions.GUEST
) {
entities.add(MenuItemEntity("隐藏", R.drawable.icon_more_panel_delete))
entities.add(MenuItemEntity(getString(R.string.article_detail_more_hide_title), R.drawable.icon_more_panel_delete))
} else {
if (mViewModel.detailEntity?.user?.id == UserManager.getInstance().userId) {
entities.add(MenuItemEntity("删除", R.drawable.icon_more_panel_delete))
entities.add(MenuItemEntity(getString(R.string.article_detail_more_delete_title), R.drawable.icon_more_panel_delete))
}
}
// 置顶/取消置顶
if (mViewModel.detailEntity?.me?.isModerator == true
&& mViewModel.detailEntity?.me?.isCommunityTop == false
&& (moderatorPermissions?.topCommunityArticle ?: Permissions.GUEST) > Permissions.GUEST) {
entities.add(MenuItemEntity(getString(R.string.article_detail_more_top_title), R.drawable.icon_more_panel_top))
} else if (mViewModel.detailEntity?.me?.isModerator == true
&& mViewModel.detailEntity?.me?.isCommunityTop == true
&& (moderatorPermissions?.cancelTopCommunityArticle ?: Permissions.GUEST) > Permissions.GUEST) {
entities.add(MenuItemEntity(getString(R.string.article_detail_more_cancel_top_title), R.drawable.icon_more_panel_top_cancel))
}
MoreFunctionPanelDialog.showMoreDialog(
requireActivity() as AppCompatActivity, entities, mViewModel.detailEntity?.title
?: "", getShareEntity(), mViewModel.detailEntity?.status ?: "", tag ?: ""
@ -597,7 +638,7 @@ class ArticleDetailFragment : BaseCommentFragment<CommentItemData, ArticleDetail
return {
val bbsType = if (mViewModel.detailEntity?.type == "game_bbs") "游戏论坛" else "综合论坛"
when (it?.text) {
"修改" -> {
getString(R.string.article_detail_more_edit_title) -> {
startActivityForResult(
ArticleEditActivity.getPatchIntent(
requireContext(),
@ -610,7 +651,7 @@ class ArticleDetailFragment : BaseCommentFragment<CommentItemData, ArticleDetail
?: "", mViewModel.detailEntity?.community?.id ?: "", bbsType
)
}
"投诉" -> {
getString(R.string.article_detail_more_complaint_title) -> {
ifLogin("帖子详情") {
BbsReportHelper.showReportDialog(mViewModel.detailEntity?.id ?: "")
}
@ -620,7 +661,7 @@ class ArticleDetailFragment : BaseCommentFragment<CommentItemData, ArticleDetail
?: "", mViewModel.detailEntity?.community?.id ?: "", bbsType
)
}
"申请加精" -> {
getString(R.string.article_detail_more_apply_select_title) -> {
if (mViewModel.detailEntity?.getSimplifyChoicenessStatus() == "apply") {
ToastUtils.showToast("申请加精审核中")
} else {
@ -632,7 +673,7 @@ class ArticleDetailFragment : BaseCommentFragment<CommentItemData, ArticleDetail
)
}
}
"加精选" -> {
getString(R.string.article_detail_more_select_title) -> {
if (mViewModel.detailEntity?.getSimplifyChoicenessStatus() == "apply") {
ToastUtils.showToast("加精审核中")
} else {
@ -644,10 +685,10 @@ class ArticleDetailFragment : BaseCommentFragment<CommentItemData, ArticleDetail
)
}
}
"取消精选" -> {
getString(R.string.article_detail_more_unselect_title) -> {
showHighlightDialog(false)
}
"修改活动标签" -> {
getString(R.string.article_detail_more_edit_activity_tag_title) -> {
ChooseActivityDialogFragment.show(
requireActivity() as AppCompatActivity,
ChooseActivityDialogFragment.ActivityLabelLocation.BBS_ARTICLE,
@ -656,7 +697,8 @@ class ArticleDetailFragment : BaseCommentFragment<CommentItemData, ArticleDetail
tag ?: ""
)
}
"删除", "隐藏" -> {
getString(R.string.article_detail_more_delete_title),
getString(R.string.article_detail_more_hide_title) -> {
DialogHelper.showDialog(
requireContext(),
"提示",
@ -673,6 +715,26 @@ class ArticleDetailFragment : BaseCommentFragment<CommentItemData, ArticleDetail
?: "", mViewModel.detailEntity?.community?.id ?: "", bbsType
)
}
getString(R.string.article_detail_more_top_title) -> {
TopCommunityCategoryDialog.show(
childFragmentManager
) { category ->
mViewModel.topCommunityArticle(category.id)
}
}
getString(R.string.article_detail_more_cancel_top_title) -> {
DialogHelper.showDialog(
requireContext(),
getString(R.string.article_detail_cancel_top_dialog_title),
getString(R.string.article_detail_cancel_top_dialog_hint),
getString(R.string.article_detail_cancel_top_dialog_confirm),
getString(R.string.article_detail_cancel_top_dialog_cancel),
confirmClickCallback = {
mViewModel.cancelTopCommunityArticle()
},
extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true)
)
}
}
}
}

View File

@ -57,6 +57,7 @@ class ArticleDetailViewModel(
val mFollowLiveData = MutableLiveData<Boolean>()
val hide = MutableLiveData<Boolean>()
val top = MutableLiveData<Boolean>()
val like = MutableLiveData<VoteEntity>()
val dislike = MutableLiveData<Boolean>()
val highlight = MutableLiveData<Boolean>()
@ -377,6 +378,52 @@ class ArticleDetailViewModel(
})
}
fun topCommunityArticle(topCategoryId: String) {
detailEntity?.let {articleDetail ->
mApi.topCommunityArticle(
articleDetail.id,
articleDetail.communityId,
mapOf(
"title" to articleDetail.title,
"top_category_id" to topCategoryId
).toRequestBody()
)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Response<ResponseBody>() {
override fun onResponse(response: ResponseBody?) {
getArticleDetail()
top.postValue(true)
}
})
}
}
fun cancelTopCommunityArticle() {
detailEntity?.also {articleDetail ->
articleDetail.top?.let { communityTop ->
mApi.cancelTopCommunityArticle(
articleDetail.id,
communityId,
mapOf(
"community_article_top_id" to communityTop.id
).toRequestBody()
)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Response<ResponseBody>() {
override fun onResponse(response: ResponseBody?) {
getArticleDetail()
top.postValue(false)
}
})
}
}
}
fun modifyArticleActivityTag(
articleId: String,
label: ActivityLabelEntity?

View File

@ -0,0 +1,65 @@
package com.gh.gamecenter.qa.article.detail
import android.view.ViewGroup
import androidx.recyclerview.widget.DiffUtil.ItemCallback
import androidx.recyclerview.widget.ListAdapter
import androidx.recyclerview.widget.RecyclerView.NO_POSITION
import androidx.recyclerview.widget.RecyclerView.ViewHolder
import com.gh.gamecenter.common.utils.layoutInflater
import com.gh.gamecenter.databinding.ItemTopCommunityCategoryBinding
import com.gh.gamecenter.qa.entity.TopCommunityCategory
class TopCommunityCategoryAdapter(
private val callback: (TopCommunityCategory) -> Unit
) : ListAdapter<TopCommunityCategory, TopCommunityCategoryAdapter.ArticleDetailTopCategoryViewHolder>(COMPARATOR) {
private var selectedPosition = -1
companion object {
private val COMPARATOR = object: ItemCallback<TopCommunityCategory>() {
override fun areItemsTheSame(
oldItem: TopCommunityCategory,
newItem: TopCommunityCategory
) : Boolean = oldItem == newItem
override fun areContentsTheSame(
oldItem: TopCommunityCategory,
newItem: TopCommunityCategory
) : Boolean = oldItem == newItem
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ArticleDetailTopCategoryViewHolder =
ArticleDetailTopCategoryViewHolder(
ItemTopCommunityCategoryBinding.inflate(
parent.layoutInflater,
parent,
false
)
)
override fun onBindViewHolder(holder: ArticleDetailTopCategoryViewHolder, position: Int) {
val titleView = holder.binding.root
titleView.text = getItem(position).title
titleView.isSelected = selectedPosition == position
titleView.setOnClickListener {
val pos = holder.bindingAdapterPosition
if (pos == NO_POSITION) return@setOnClickListener
it.isSelected = true
val oldPos = selectedPosition
selectedPosition = pos
notifyItemChanged(oldPos)
callback.invoke(getItem(pos))
}
}
class ArticleDetailTopCategoryViewHolder(
val binding: ItemTopCommunityCategoryBinding
) : ViewHolder(binding.root)
}

View File

@ -0,0 +1,93 @@
package com.gh.gamecenter.qa.article.detail
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.fragment.app.FragmentManager
import androidx.fragment.app.viewModels
import androidx.recyclerview.widget.GridLayoutManager
import com.gh.gamecenter.common.utils.observeNonNull
import com.gh.gamecenter.common.view.GridSpacingItemDecoration
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.databinding.DialogTopCommunityCategoryBinding
import com.gh.gamecenter.qa.entity.TopCommunityCategory
import com.google.android.material.bottomsheet.BottomSheetDialogFragment
/**
* 版主帖子置顶-置顶类型
*/
class TopCommunityCategoryDialog private constructor(): BottomSheetDialogFragment() {
private val viewModel: TopCommunityCategoryViewModel by viewModels()
private lateinit var viewBinding: DialogTopCommunityCategoryBinding
private lateinit var topCommunityCategoryAdapter: TopCommunityCategoryAdapter
private lateinit var callback: (TopCommunityCategory) -> Unit
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
viewModel.getTopCommunityCategory()
}
override fun onCreateView(
inflater: LayoutInflater,
container: ViewGroup?,
savedInstanceState: Bundle?
): View = DialogTopCommunityCategoryBinding
.inflate(
inflater,
container,
false
).also {
viewBinding = it
}.root
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
with(viewBinding) {
rv.adapter = TopCommunityCategoryAdapter{
viewModel.submitTopCommunityCategory(it)
}.also {
topCommunityCategoryAdapter = it
}
rv.layoutManager = GridLayoutManager(context, 2)
rv.addItemDecoration(GridSpacingItemDecoration(2, DisplayUtils.dip2px(8F), false))
}
viewModel.topCommunityCategoryList.observeNonNull(viewLifecycleOwner) {
topCommunityCategoryAdapter.submitList(it)
}
viewModel.selectTopCommunityCategory.observe(viewLifecycleOwner) {
if (it == null) {
viewBinding.tvSubmit.isEnabled = false
viewBinding.tvSubmit.alpha = 0.4F
} else {
viewBinding.tvSubmit.isEnabled = true
viewBinding.tvSubmit.alpha = 1.0F
}
}
viewBinding.ivClose.setOnClickListener {
dismissAllowingStateLoss()
}
viewBinding.tvSubmit.setOnClickListener {
callback.invoke(viewModel.selectTopCommunityCategory.value!!)
dismissAllowingStateLoss()
}
}
companion object {
fun show(
fragmentManager: FragmentManager,
callback: (TopCommunityCategory) -> Unit
) = TopCommunityCategoryDialog().also {
it.callback = callback
}.show(fragmentManager, null)
}
}

View File

@ -0,0 +1,40 @@
package com.gh.gamecenter.qa.article.detail
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import com.gh.gamecenter.common.retrofit.Response
import com.gh.gamecenter.qa.entity.TopCommunityCategory
import com.gh.gamecenter.retrofit.RetrofitManager
import com.gh.gamecenter.retrofit.service.ApiService
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
/**
* 论坛置顶类型
*/
class TopCommunityCategoryViewModel: ViewModel() {
private val mApi: ApiService = RetrofitManager.getInstance().api
val topCommunityCategoryList = MutableLiveData<List<TopCommunityCategory>>()
val selectTopCommunityCategory = MutableLiveData<TopCommunityCategory?>(null)
fun getTopCommunityCategory() {
mApi.topCommunityCategory
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Response<List<TopCommunityCategory>>() {
override fun onResponse(response: List<TopCommunityCategory>?) {
response?.let {
topCommunityCategoryList.value = it
}
}
})
}
fun submitTopCommunityCategory(category: TopCommunityCategory) {
selectTopCommunityCategory.value = category
}
}

View File

@ -5,6 +5,7 @@ import android.app.Activity
import android.app.Dialog
import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.util.DisplayMetrics
import android.view.LayoutInflater
@ -13,6 +14,8 @@ import android.view.inputmethod.InputMethodManager
import android.widget.*
import androidx.core.content.ContextCompat
import androidx.core.os.bundleOf
import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.RecyclerView
@ -305,8 +308,22 @@ open class NewCommentFragment : ListFragment<CommentEntity, NewCommentViewModel>
commentContainer?.layoutParams = layoutParams
}
mKeyboardHeightProvider = KeyboardHeightProvider(activity)
view.post { mKeyboardHeightProvider?.start() }
// 判断是否处于平板的平行视界模式
val configString = requireContext().resources.configuration.toString()
val isMagicMode = configString.contains("magic-window") || configString.contains("window-magic")
// 平板上的导航方式改成按键时,使用 KeyboardHeightProvider 的 PopupWindow 会拦截掉所有的触摸事件
// 根据测试 Android 11 以前的系统用 WindowInsetsCompat.Type.ime()).bottom 获取不到正确的值
// 所以仅在系统为大于 10 且处于平行视界模式时才切换实现
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.R && isMagicMode) {
ViewCompat.setOnApplyWindowInsetsListener(requireActivity().window.decorView) { _: View?, insets: WindowInsetsCompat ->
onKeyboardHeightChanged(insets.getInsets(WindowInsetsCompat.Type.ime()).bottom, 0)
insets
}
} else {
mKeyboardHeightProvider = KeyboardHeightProvider(activity)
view.post { mKeyboardHeightProvider?.start() }
}
val emptyHint = mCachedView?.findViewById<TextView>(R.id.reuseNoneDataTv)
emptyHint?.text = "这里还没有人评论噢~"
emptyHint?.setTextColor(R.color.background_white.toColor(requireContext()))

View File

@ -7,6 +7,7 @@ import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.ViewGroup.MarginLayoutParams
import android.widget.LinearLayout
import android.widget.TextView
import androidx.appcompat.app.AppCompatActivity
@ -151,8 +152,14 @@ class MoreFunctionPanelDialog : BaseDraggableDialogFragment() {
}
private fun addActionItem() {
mMenuItems.forEachIndexed { _, menuItemEntity ->
val itemView = createItemView(menuItemEntity)
mMenuItems.forEachIndexed { index, menuItemEntity ->
val itemView = createItemView(menuItemEntity).apply {
if (index == mMenuItems.lastIndex) {
(layoutParams as MarginLayoutParams).apply {
rightMargin = 16F.dip2px()
}
}
}
itemView.setOnClickListener {
debounceActionWithInterval(it.id, 2000) {
if (menuItemEntity.isEnable) {

View File

@ -3,7 +3,6 @@ package com.gh.gamecenter.qa.entity
import android.os.Parcelable
import com.gh.gamecenter.common.entity.CommunityEntity
import com.gh.gamecenter.common.entity.LinkEntity
import com.gh.gamecenter.entity.ForumEntity
import com.gh.gamecenter.feature.entity.UserEntity
import com.gh.gamecenter.feature.entity.*
import com.google.gson.annotations.SerializedName
@ -48,7 +47,9 @@ class ArticleDetailEntity(
val activityTag: ActivityTagEntity? = null,
var sections: List<SectionEntity> = ArrayList(),
@SerializedName("section_id")
var sectionIdList: List<String> = ArrayList()
var sectionIdList: List<String> = ArrayList(),
@SerializedName("community_article_top")
var top: CommunityTopEntity? = null
) : Parcelable {
fun getSimplifyChoicenessStatus(): String {
@ -58,6 +59,10 @@ class ArticleDetailEntity(
else -> choicenessStatus ?: ""
}
}
companion object {
const val STATUS_PASS = "pass"
}
}
@Parcelize

View File

@ -36,7 +36,7 @@ class EditorInsertEntity(
fun transform(article: ArticleEntity): EditorInsertEntity {
val entity = EditorInsertEntity()
entity.id = article.id
entity.communityId = article.bbs.id
entity.communityId = article.community.id
entity.type = "community_article"
entity.title = article.title.eliminateDoubleQuote()
entity.brief = article.brief.eliminateDoubleQuote()

View File

@ -56,7 +56,9 @@ class QuestionsDetailEntity(
val source: SourceEntity? = null,
@SerializedName("activity_tag")
val activityTag: ActivityTagEntity? = null,
var sections: List<SectionEntity> = ArrayList()
var sections: List<SectionEntity> = ArrayList(),
@SerializedName("question_top")
var top: CommunityTopEntity? = null
) : Parcelable {
fun getFollowCount(): Int {

View File

@ -0,0 +1,19 @@
package com.gh.gamecenter.qa.entity
import android.os.Parcelable
import com.google.gson.annotations.SerializedName
import kotlinx.parcelize.Parcelize
@Parcelize
data class TopCommunityCategory(
@SerializedName("_id")
val id: String, // 置顶类型ID
val title: String, // 置顶类型名称
val style: Style
): Parcelable {
@Parcelize
data class Style(
val color: String,
val fontColor: String
): Parcelable
}

View File

@ -32,9 +32,11 @@ import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.databinding.FragmentArticleDetailBinding
import com.gh.gamecenter.entity.MenuItemEntity
import com.gh.gamecenter.eventbus.EBDeleteDetail
import com.gh.gamecenter.eventbus.EBTopCommunityChanged
import com.gh.gamecenter.feature.entity.Permissions
import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.qa.article.detail.CommentItemData
import com.gh.gamecenter.qa.article.detail.TopCommunityCategoryDialog
import com.gh.gamecenter.qa.comment.CommentActivity
import com.gh.gamecenter.qa.comment.base.BaseCommentAdapter
import com.gh.gamecenter.qa.comment.base.BaseCommentFragment
@ -367,6 +369,22 @@ class NewQuestionDetailFragment :
mViewModel.updateDetailLiveData.observeNonNull(this) {
mAdapter?.questionDetailVH?.bindView(it)
}
mViewModel.top.observeNonNull(this) { top ->
val topSuccessToast = if(top) {
R.string.article_detail_top_success_toast
} else {
R.string.article_detail_cancel_top_success_toast
}
toast(getString(topSuccessToast))
mListViewModel.questionDetail?.let {
EventBus.getDefault().post(
EBTopCommunityChanged(
it.community.id
)
)
}
}
}
private fun updateStartButton() {
@ -545,6 +563,17 @@ class NewQuestionDetailFragment :
}
}
// 置顶/取消置顶
if (questionEntity.me.isModerator
&& !questionEntity.me.isCommunityTop
&& moderatorPermissions.topQuestion > Permissions.GUEST) {
entities.add(MenuItemEntity(getString(R.string.article_detail_more_top_title), R.drawable.icon_more_panel_top))
} else if (questionEntity.me.isModerator
&& questionEntity.me.isCommunityTop
&& moderatorPermissions.cancelTopQuestion > Permissions.GUEST) {
entities.add(MenuItemEntity(getString(R.string.article_detail_more_cancel_top_title), R.drawable.icon_more_panel_top_cancel))
}
MoreFunctionPanelDialog.showMoreDialog(
requireActivity() as AppCompatActivity, entities, questionEntity.title
?: "", getShareEntity(questionEntity), questionEntity.status, tag ?: ""
@ -655,6 +684,29 @@ class NewQuestionDetailFragment :
bbsType
)
}
getString(R.string.article_detail_more_top_title) -> {
TopCommunityCategoryDialog.show(
childFragmentManager
) { category ->
mViewModel.topCommunityQuestion(category.id)
}
}
getString(R.string.article_detail_more_cancel_top_title) -> {
DialogHelper.showDialog(
requireContext(),
getString(R.string.article_detail_cancel_top_dialog_title),
getString(R.string.article_detail_cancel_top_dialog_hint),
getString(R.string.article_detail_cancel_top_dialog_confirm),
getString(R.string.article_detail_cancel_top_dialog_cancel),
confirmClickCallback = {
mViewModel.questionDetail?.top?.let { top ->
mViewModel.cancelTopCommunityQuestion()
}
},
extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true)
)
}
}
}
}

View File

@ -57,6 +57,7 @@ class NewQuestionDetailViewModel(
val moderatorsHideLiveData = MutableLiveData<Boolean>()
val favoriteLiveData = MutableLiveData<Boolean>()
val mFollowLiveData = MutableLiveData<Boolean>()
val top = MutableLiveData<Boolean>()
val updateDetailLiveData = MutableLiveData<QuestionsDetailEntity>()
var questionDetail: QuestionsDetailEntity? = null
val followLiveData = mFollowLiveData
@ -226,6 +227,49 @@ class NewQuestionDetailViewModel(
})
}
fun topCommunityQuestion(topCategoryId: String) {
questionDetail?.let { questionDetail ->
mApi.topCommunityQuestion(
questionDetail.id,
mapOf(
"title" to questionDetail.title,
"top_category_id" to topCategoryId
).toRequestBody()
)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Response<ResponseBody>() {
override fun onResponse(response: ResponseBody?) {
getQuestionDetail()
top.postValue(true)
}
})
}
}
fun cancelTopCommunityQuestion() {
questionDetail?.also {questionDetail ->
questionDetail.top?.let { communityTop ->
mApi.cancelTopCommunityQuestion(
questionDetail.id,
mapOf(
"question_top_id" to communityTop.id
).toRequestBody()
)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Response<ResponseBody>() {
override fun onResponse(response: ResponseBody?) {
getQuestionDetail()
top.postValue(false)
}
})
}
}
}
fun getFirstAnswer() = mListLiveData.value?.safelyGetInRelease(0)
class Factory(

View File

@ -41,12 +41,14 @@ import com.gh.gamecenter.entity.*
import com.gh.gamecenter.eventbus.EBDeleteDetail
import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.gh.gamecenter.eventbus.EBPackage
import com.gh.gamecenter.eventbus.EBTopCommunityChanged
import com.gh.gamecenter.feature.entity.ForumVideoEntity
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.entity.Permissions
import com.gh.gamecenter.forum.home.ForumScrollCalculatorHelper
import com.gh.gamecenter.gamedetail.GameDetailFragment
import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.qa.article.detail.TopCommunityCategoryDialog
import com.gh.gamecenter.qa.dialog.ChooseActivityDialogFragment
import com.gh.gamecenter.qa.dialog.MoreFunctionPanelDialog
import com.gh.gamecenter.qa.video.detail.comment.VideoCommentFragment
@ -309,6 +311,21 @@ class ForumVideoDetailFragment : BaseFragment_TabLayout() {
toast("提交失败")
}
}
mViewModel.top.observeNonNull(this) { top ->
val topSuccessToast = if(top) {
R.string.article_detail_top_success_toast
} else {
R.string.article_detail_cancel_top_success_toast
}
toast(getString(topSuccessToast))
mForumVideoEntity?.let {
EventBus.getDefault().post(
EBTopCommunityChanged(
it.bbsId
)
)
}
}
}
private fun setGameInfo(entity: ForumVideoEntity) {
@ -535,6 +552,17 @@ class ForumVideoDetailFragment : BaseFragment_TabLayout() {
}
}
// 置顶/取消置顶
if (mForumVideoEntity?.me?.isModerator == true
&& mForumVideoEntity?.me?.isCommunityTop == false
&& (moderatorPermissions?.topVideo ?: Permissions.GUEST) > Permissions.GUEST) {
entities.add(MenuItemEntity(getString(R.string.article_detail_more_top_title), R.drawable.icon_more_panel_top))
} else if (mForumVideoEntity?.me?.isModerator == true
&& mForumVideoEntity?.me?.isCommunityTop == true
&& (moderatorPermissions?.cancelTopVideo ?: Permissions.GUEST) > Permissions.GUEST) {
entities.add(MenuItemEntity(getString(R.string.article_detail_more_cancel_top_title), R.drawable.icon_more_panel_top_cancel))
}
MoreFunctionPanelDialog.showMoreDialog(
requireActivity() as AppCompatActivity, entities, mForumVideoEntity?.title
?: "", getShareEntity(), mForumVideoEntity?.status ?: "", tag ?: ""
@ -647,6 +675,27 @@ class ForumVideoDetailFragment : BaseFragment_TabLayout() {
?: "", mForumVideoEntity?.bbs?.id ?: "", bbsType
)
}
getString(R.string.article_detail_more_top_title) -> {
TopCommunityCategoryDialog.show(
childFragmentManager
) { category ->
mViewModel.topCommunityVideo(category.id)
}
}
getString(R.string.article_detail_more_cancel_top_title) -> {
DialogHelper.showDialog(
requireContext(),
getString(R.string.article_detail_cancel_top_dialog_title),
getString(R.string.article_detail_cancel_top_dialog_hint),
getString(R.string.article_detail_cancel_top_dialog_confirm),
getString(R.string.article_detail_cancel_top_dialog_cancel),
confirmClickCallback = {
mViewModel.cancelTopCommunityVideo()
},
extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true)
)
}
}
}
}

View File

@ -23,6 +23,7 @@ import com.gh.gamecenter.feature.entity.Permissions
import com.gh.gamecenter.retrofit.RetrofitManager
import com.google.gson.JsonObject
import com.halo.assistant.HaloApp
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import okhttp3.ResponseBody
import retrofit2.HttpException
@ -43,6 +44,7 @@ class ForumVideoDetailViewModel(
val highlight = MutableLiveData<Boolean>()
val cancelHighlight = MutableLiveData<Boolean>()
val applyHighlight = MutableLiveData<Boolean>()
val top = MutableLiveData<Boolean>()
var currentToolbarStatus = true
init {
@ -200,6 +202,49 @@ class ForumVideoDetailViewModel(
runOnIoThread { tryCatchInRelease { HistoryDatabase.instance.videoHistoryDao().addVideo(videoHistory) } }
}
fun topCommunityVideo(topCategoryId: String) {
detailLiveData.value?.data?.let { videoDetail ->
mApi.topCommunityVideo(
videoDetail.id,
mapOf(
"title" to videoDetail.title,
"top_category_id" to topCategoryId
).toRequestBody()
)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Response<ResponseBody>() {
override fun onResponse(response: ResponseBody?) {
getVideoDetail()
top.postValue(true)
}
})
}
}
fun cancelTopCommunityVideo() {
detailLiveData.value?.data
?.also {videoDetail ->
videoDetail.top?.let { communityTop ->
mApi.cancelTopCommunityVideo(
videoDetail.id,
mapOf(
"video_top_id" to communityTop.id
).toRequestBody()
)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Response<ResponseBody>() {
override fun onResponse(response: ResponseBody?) {
getVideoDetail()
top.postValue(false)
}
})
}
}
}
fun isTopVideoPartlyCached(topVideoUrl: String): Boolean {
val cache = ExoSourceManager.getCacheSingleInstance(HaloApp.getInstance().application, null)
val key = Uri.parse(topVideoUrl).toString()

View File

@ -269,7 +269,11 @@ class VideoDescTopViewHolder(
private fun getTextViewHeight(view: TextView, lineCount: Int = 0): Int {
if (view.visibility == View.GONE) return 0
val layout: Layout = view.layout ?: return 0
val desired: Int = layout.getLineTop(if (lineCount > 0) lineCount else view.lineCount)
val desired: Int = try {
layout.getLineTop(if (lineCount > 0) lineCount else view.lineCount)
} catch (e: ArrayIndexOutOfBoundsException) {
layout.getLineTop(view.lineCount)
}
val padding = view.compoundPaddingTop + view.compoundPaddingBottom
return desired + padding
}

View File

@ -40,7 +40,6 @@ import com.gh.gamecenter.entity.GameCollectionTagEntity;
import com.gh.gamecenter.entity.GameColumnCollection;
import com.gh.gamecenter.entity.GameDigestEntity;
import com.gh.gamecenter.entity.GameGuidePopupEntity;
import com.gh.gamecenter.entity.GameNavigationWrapper;
import com.gh.gamecenter.entity.GameServerTestV2Entity;
import com.gh.gamecenter.entity.GameVideoInfo;
import com.gh.gamecenter.entity.GamesCollectionDetailEntity;
@ -114,6 +113,7 @@ import com.gh.gamecenter.gamedetail.entity.BigEvent;
import com.gh.gamecenter.gamedetail.entity.NewGameDetailEntity;
import com.gh.gamecenter.login.entity.UserInfoEntity;
import com.gh.gamecenter.personalhome.rating.MyRating;
import com.gh.gamecenter.qa.entity.TopCommunityCategory;
import com.gh.gamecenter.qa.entity.AnswerDetailEntity;
import com.gh.gamecenter.qa.entity.AnswerDraftEntity;
import com.gh.gamecenter.qa.entity.ArticleDetailEntity;
@ -193,13 +193,6 @@ public interface ApiService {
@GET("region_setting")
Single<RegionSetting> getRegionSetting(@Query("channel") String channel);
/**
* 统计下载量
*/
@Headers({"Content-Type: application/json", "Accept: application/json"})
@POST("stat/download")
Observable<ResponseBody> postDownload(@Body RequestBody body);
/**
* 根据包名获取游戏摘要
*/
@ -497,6 +490,12 @@ public interface ApiService {
@POST("articles/comments/{comment_id}:vote")
Observable<ResponseBody> postCommentVote(@Path("comment_id") String comment_id);
/**
* 评论点赞
*/
@POST("articles/comments/{comment_id}:hide")
Observable<ResponseBody> deleteComment(@Path("comment_id") String comment_id);
/**
* 获取新闻评论
*/
@ -1348,6 +1347,56 @@ public interface ApiService {
@POST("communities/articles/{article_id}:hide")
Observable<ResponseBody> hideCommunityArticle(@Path("article_id") String articleId);
/**
* 获取置顶帖子类型
*/
@GET("communities/top_category")
Observable<List<TopCommunityCategory>> getTopCommunityCategory();
/**
* 普通帖-置顶
*/
@POST("communities/{community_id}/articles/{article_id}:set-top")
Observable<ResponseBody> topCommunityArticle(@Path("article_id") String articleId,
@Path("community_id") String communityId,
@Body RequestBody body);
/**
* 普通帖-取消置顶
*/
@POST("communities/{community_id}/articles/{article_id}:cancel-top")
Observable<ResponseBody> cancelTopCommunityArticle(@Path("article_id") String articleId,
@Path("community_id") String communityId,
@Body RequestBody body);
/**
* 提问帖-置顶
*/
@POST("question/{question_id}:set-top")
Observable<ResponseBody> topCommunityQuestion(@Path("question_id") String questionId,
@Body RequestBody body);
/**
* 提问帖-取消置顶
*/
@POST("question/{question_id}:cancel-top")
Observable<ResponseBody> cancelTopCommunityQuestion(@Path("question_id") String questionId,
@Body RequestBody body);
/**
* 视频帖-置顶
*/
@POST("video/{video_id}:set-top")
Observable<ResponseBody> topCommunityVideo(@Path("video_id") String videoId,
@Body RequestBody body);
/**
* 视频帖-取消置顶
*/
@POST("video/{video_id}:cancel-top")
Observable<ResponseBody> cancelTopCommunityVideo(@Path("video_id") String videoId,
@Body RequestBody body);
/**
* 隐藏社区文章评论
@ -2062,7 +2111,7 @@ public interface ApiService {
* 获取论坛详情
*/
@GET("bbses/{bbs_id}")
Observable<ForumDetailEntity> getForumDetail(@Path("bbs_id") String bbsId);
Observable<ForumDetailEntity> getForumDetail(@Path("bbs_id") String bbsId, @Query("refresh") boolean refresh);
/**
* 获取论坛板块列表
@ -2967,7 +3016,7 @@ public interface ApiService {
* 获取我的存档列表
*/
@GET("users/games/{game_id}/archives")
Observable<List<ArchiveEntity>> getMyArchives(@Path("game_id") String gameId, @Query("page") int page);
Observable<List<ArchiveEntity>> getMyArchives(@Path("game_id") String gameId, @Query("page") int page, @Query("sort") String sort);
/**
* 创建我的存档
@ -2985,7 +3034,7 @@ public interface ApiService {
* 获取我的分享存档列表
*/
@GET("users/games/{game_id}/archives/share")
Observable<List<ArchiveEntity>> getMyShareArchives(@Path("game_id") String gameId, @Query("page") int page);
Observable<List<ArchiveEntity>> getMyShareArchives(@Path("game_id") String gameId, @Query("page") int page, @Query("sort") String sort);
/**
* 编辑我的存档

View File

@ -88,7 +88,7 @@ class GameServersActivity : DownloadToolbarActivity() {
{ MtaHelper.onEvent("开服表", "Tab", if (mServersTest?.isChecked == true) "开测" else "开服") }
// init viewpager
mFragments.add(GameServersPublishFragment())
mFragments.add(GameServersTestFragment())
mFragments.add(GameServersTestFragment().with(intent.extras))
mViewpager?.setScrollable(false)
mViewpager?.offscreenPageLimit = 1
mViewpager?.adapter = FragmentAdapter(supportFragmentManager, mFragments)

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