Compare commits

...

263 Commits

Author SHA1 Message Date
9bee5774ce chore: 版本更新至 5.22.8 2023-04-30 14:27:27 +08:00
14bf638616 feat: 屏蔽 vpn 模块,恢复神策模块 2023-04-30 14:26:57 +08:00
d4fd71cd66 chore: 版本更新为 5.22.6,去掉神策 SDK 2023-04-29 15:25:51 +08:00
7129751c44 Merge branch 'hotfix/v5.22.5-795/cloud_archive_list_crash' into 'legacy-release'
fix: 修复云存档列表页面重建出现的闪退问题...

See merge request halo/android/assistant-android!941
2023-04-20 10:31:24 +08:00
deda82b02e fix: 修复云存档列表页面重建出现的闪退问题... 2023-04-20 10:31:24 +08:00
97790e9416 Merge branch 'hotfix-v5.22.5-795-crashes' into 'legacy-release'
修复一些闪退问题

See merge request halo/android/assistant-android!935
2023-04-18 16:02:48 +08:00
ae800c2046 fix: 修复进入分类2.0页面快速退出出现的闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/246858/events/30c49600edde46d5a9afa071ddf6948d/?project=22&statsPeriod=14d 2023-04-18 15:40:13 +08:00
75de02669a fix: 修复从游戏存档已安装游戏页进入已卸载畅玩游戏的云存档管理页面点击下载按钮出现的闪退问题 https://sentry.shanqu.cc/organizations/lightgame/issues/289025/events/271d99a504674afb98041c50db3cc433/?project=22&query=String.length%28%29&statsPeriod=14d 2023-04-18 15:15:41 +08:00
beb282503d Merge branch 'hotfix-v5.22.4-794-rating_reply_download_button' into 'release'
fix: 修复评价详情页下载按钮下载时不更新进度条的问题

See merge request halo/android/assistant-android!902
2023-04-13 11:51:49 +08:00
4fc185a033 fix: 修复评价详情页下载按钮下载时不更新进度条的问题 2023-04-13 11:45:02 +08:00
5a54a85fe1 Merge branch 'hotfix-v5.22.4-794-GHZS-2028' into 'release'
fix: 礼包状态更新不限制是否登录

See merge request halo/android/assistant-android!901
2023-04-13 09:20:09 +08:00
d19e7f97d1 fix: 礼包状态更新不限制是否登录 2023-04-13 09:17:05 +08:00
0056680f4a chore: 版本更新至 5.22.5 2023-04-12 16:37:22 +08:00
1eb81d994d Merge branch 'hotfix-v5.22.4-794-game_detail_libao_crash' into 'release'
fix: 修复游戏礼包登录后点击复制会闪退的问题 https://jira.shanqu.cc/browse/GHZS-2028

See merge request halo/android/assistant-android!898
2023-04-12 16:36:32 +08:00
24949b9688 Merge branch 'fix-v5.22.4-794-meta_build' into 'release'
fix: 神策数据接受地址改成正式项目

See merge request halo/android/assistant-android!899
2023-04-12 16:36:21 +08:00
65de350da2 Merge branch 'hotfix-v5.22.4-794-meta_build_issue' into 'release'
fix: 推广打包后台功能—0330测试-客户端 https://jira.shanqu.cc/browse/GHZS-1874

See merge request halo/android/assistant-android!896
2023-04-12 16:36:09 +08:00
d02e8fbfa6 fix: 神策数据接受地址改成正式项目 2023-04-12 16:33:04 +08:00
48e8d4b631 fix: 修复游戏礼包登录后点击复制会闪退的问题 https://jira.shanqu.cc/browse/GHZS-2028 2023-04-12 16:21:18 +08:00
e4e92e0efc fix: 推广打包后台功能—0330测试-客户端 https://jira.shanqu.cc/browse/GHZS-1874 2023-04-12 15:15:18 +08:00
4126f06107 Merge branch 'hotfix-v5.22.4-794-tea_version' into 'release'
fix: 头条 SDK 基础版本升级为 6.14.3

See merge request halo/android/assistant-android!891
2023-04-10 18:03:54 +08:00
3e3f276cc4 fix: 头条 SDK 基础版本升级为 6.14.3 2023-04-10 18:01:32 +08:00
bd5902d924 chore: 版本更新至 5.22.4 2023-04-10 15:31:01 +08:00
7022cf97c8 Merge branch 'hotfix-v5.22.3-793-vspace_config_update_issue' into 'release'
fix: 修复畅玩服务工具因为初始化时序问题,有机率无法更新到最新配置的问题

See merge request halo/android/assistant-android!889
2023-04-10 15:30:22 +08:00
0452116830 fix: 修复畅玩服务工具因为初始化时序问题,有机率无法更新到最新配置的问题 2023-04-10 15:23:43 +08:00
5dfbe5c571 Merge branch 'hotfix-v5.22.3-793-change_fixed_tea_version' into 'release'
fix: 头条 SDK 版本跟随输入变更

See merge request halo/android/assistant-android!888
2023-04-10 14:01:13 +08:00
b8adfc7a4b fix: 头条 SDK 版本跟随输入变更 2023-04-10 13:58:04 +08:00
87de104da6 Merge branch 'pack-v5.22.3-793-multithread_download' into 'release'
feat: 游戏下载底层下载切换至多线程

See merge request halo/android/assistant-android!887
2023-04-10 11:15:28 +08:00
b97a68828d Merge branch 'feature-meta_build_without_multithread_download' into 'release'
feat: 【光环助手】推广组测试打包任务 https://jira.shanqu.cc/browse/GHZS-972

See merge request halo/android/assistant-android!885
2023-04-10 10:59:19 +08:00
18e96d1c0c feat: 【光环助手】推广组测试打包任务 https://jira.shanqu.cc/browse/GHZS-972 2023-04-10 10:04:32 +08:00
316778e8a5 feat: 底层下载切换至多线程 2023-04-06 10:31:12 +08:00
210f731b59 chore: 版本更新至 5.22.3 2023-04-06 10:29:32 +08:00
9e6816440b Merge branch 'hotfix-v5.22.2-792-crashes' into 'release'
处理线上测试包 5.22 的相关闪退

See merge request halo/android/assistant-android!879
2023-04-06 09:24:22 +08:00
128fea4446 fix: 修复游戏详情页快速跳转时的闪退 https://sentry.shanqu.cc/organizations/lightgame/issues/285364/?project=22&query=dist%3A792&statsPeriod=14d 2023-04-05 10:19:37 +08:00
7e6e85469c fix: 修复刷新延时触发的空指针闪退 https://sentry.shanqu.cc/organizations/lightgame/issues/283770/events/9e0110112aa34b369fdfe89f00fe41f8/?project=22&query=LazyListFragment&statsPeriod=14d 2023-04-05 10:09:06 +08:00
d9c1108dfe fix: 捕抓游戏详情顶部视频暂停时显示占位图所有的异常 2023-04-05 10:01:24 +08:00
86b79d6240 fix: 修复接收卸载应用广播时偶发的数组越界闪退 https://sentry.shanqu.cc/organizations/lightgame/issues/240065/events/0ea60d852bd9400faa6ab2fc611be890/?project=22&query=dist%3A792&statsPeriod=14d 2023-04-05 10:00:29 +08:00
acd308eb00 Merge branch 'hotfix-v5.22.1-791-gid' into 'release'
处理神策 gid 绑定问题

See merge request halo/android/assistant-android!877
2023-04-04 15:35:19 +08:00
c0937b7393 fix: 补充 gid 变更的数据上报,以及神策的临时 gid 解绑操作 2023-04-04 15:27:18 +08:00
62b9e8a76c chore: 版本更新至 5.22.2 2023-04-04 10:35:52 +08:00
76b3607c7f Merge branch 'hotfix-v5.22.1-791-crash' into 'release'
fix: 修复游戏详情页顶部视频闪退

See merge request halo/android/assistant-android!875
2023-04-04 10:27:07 +08:00
619ca32a4a fix: 修复游戏详情页顶部视频闪退 2023-04-04 10:16:03 +08:00
2bd9b7cfe2 Merge branch 'feat-GHZS-1870' into 'release'
feat: VPN预授权弹窗文案修改 https://jira.shanqu.cc/browse/GHZS-1869

See merge request halo/android/assistant-android!874
2023-04-04 09:22:33 +08:00
c93978c773 feat: VPN预授权弹窗文案修改 https://jira.shanqu.cc/browse/GHZS-1869 2023-04-04 09:20:51 +08:00
60b3c25162 Merge branch 'fix-GHZS-1976' into 'release'
fix:【光环助手】神策分析报告问题(2、4) https://jira.shanqu.cc/browse/GHZS-1976

See merge request halo/android/assistant-android!872
2023-04-03 17:32:44 +08:00
8ac408b5c8 fix:【光环助手】神策分析报告问题(2、4) https://jira.shanqu.cc/browse/GHZS-1976 2023-04-03 17:18:19 +08:00
b9ea681431 Merge branch 'hotfix-v5.22.0-790-crashes' into 'release'
fix: 修复快速跳转页面时游戏详情顶部视频 mTextureView 为空导致的闪退

See merge request halo/android/assistant-android!870
2023-04-03 14:38:49 +08:00
2fb956cd3b fix: 修复快速跳转页面时游戏详情顶部视频 mTextureView 为空导致的闪退 2023-04-03 14:32:46 +08:00
b18d268f73 chore: 版本更新至 5.22.1 2023-04-03 13:54:25 +08:00
2e4c341bb2 Merge branch 'hotfix-v5.22.0-570-crashes' into 'release'
Hotfix v5.22.0 570 crashes

See merge request halo/android/assistant-android!869
2023-04-03 12:00:06 +08:00
bfed223640 fix: 修复游戏详情页顶部视频播放控件暂停 bitmap 被回收后的闪退问题 2023-04-03 11:49:23 +08:00
5bf74b5631 fix: 修复多线程遍历安装包监听对象变更时的闪退 2023-04-03 11:48:28 +08:00
fd16bc33ef chore: 更新神策 SDK 版本至 6.6.6 2023-04-03 10:21:07 +08:00
393f0942ad Merge branch 'fix-sensor' into 'dev'
fix: 调整神策 URL 存放位置,屏蔽神策 SDK 获取 MAC, IMEI 等相关数据

See merge request halo/android/assistant-android!851
2023-03-28 10:58:58 +08:00
a57f8ed305 fix: 调整神策 URL 存放位置,屏蔽神策 SDK 获取 MAC, IMEI 等相关数据 2023-03-28 10:55:10 +08:00
6fcfc2f4be Merge branch 'fix-GHZS-1788' into 'dev'
fix: 神策数据埋点第一期—0323测试(调整AppLaunch事件) https://jira.shanqu.cc/browse/GHZS-1788

See merge request halo/android/assistant-android!849
2023-03-28 09:47:17 +08:00
0ffbba06fc fix: 神策数据埋点第一期—0323测试(调整AppLaunch事件) https://jira.shanqu.cc/browse/GHZS-1788 2023-03-28 09:21:42 +08:00
baf33ca5db Merge branch 'fix-sensors' into 'dev'
fix: 修复无法切换测试环境的问题

See merge request halo/android/assistant-android!847
2023-03-27 18:04:39 +08:00
5f4ebea65e fix: 修复无法切换测试环境的问题 2023-03-27 16:46:18 +08:00
13d90793c4 Merge branch 'fix-GHZS-1783' into 'dev'
fix: 云存档点击问题 https://jira.shanqu.cc/browse/GHZS-1783

See merge request halo/android/assistant-android!844
2023-03-27 14:07:51 +08:00
85ab438e5f fix: 云存档点击问题 https://jira.shanqu.cc/browse/GHZS-1783 2023-03-27 14:05:16 +08:00
948adaa5ec Merge remote-tracking branch 'origin/release' into dev
# Conflicts:
#	app/src/main/java/com/gh/gamecenter/SplashScreenActivity.kt
2023-03-27 13:48:41 +08:00
88dc6584e7 Merge branch 'hotfix-v5.21.0-770-crashes' into 'release'
Hotfix v5.21.0 770 crashes

See merge request halo/android/assistant-android!843
2023-03-27 11:30:13 +08:00
7ed06b6c06 fix: 捕抓清理清理 APK 页面调起安装时没有 Activity 响应的问题 2023-03-27 11:26:15 +08:00
aa7bc499b2 fix: 捕抓畅玩 ContentProvider 数据插入异常 2023-03-27 11:24:51 +08:00
126064c7f1 fix: 修复系统内存不足时启动光环或重启光环造成的闪退 2023-03-27 10:51:36 +08:00
90de69b338 Merge branch 'fix-GHZS-1788' into 'dev'
fix: 神策数据埋点第一期—0323测试 https://jira.shanqu.cc/browse/GHZS-1788

See merge request halo/android/assistant-android!841
2023-03-24 16:13:42 +08:00
a16c52980f fix: 神策数据埋点第一期—0323测试 https://jira.shanqu.cc/browse/GHZS-1788 2023-03-24 15:32:07 +08:00
9b0c9aceb8 Merge branch 'fix-GHZS-1790' into 'dev'
fix:【光环助手】同步正式环境问题-新发布的视频帖详情页展示错误 https://jira.shanqu.cc/browse/GHZS-1790

See merge request halo/android/assistant-android!839
2023-03-24 11:29:42 +08:00
e9c00b4a32 fix:【光环助手】同步正式环境问题-新发布的视频帖详情页展示错误 https://jira.shanqu.cc/browse/GHZS-1790 2023-03-24 11:04:32 +08:00
e2106dd7ca Merge branch 'fix-package_observer_crash' into 'dev'
fix: 修复多线程注册取消注册包名变更回调引起的闪退问题

See merge request halo/android/assistant-android!834
2023-03-23 09:57:00 +08:00
aad3186a5e fix: 修复多线程注册取消注册包名变更回调引起的闪退问题 2023-03-23 09:37:25 +08:00
311e2292be Merge branch 'fix-GHZS-1629' into 'dev'
fix: 神策数据埋点第一期--光环助手(修改游戏单相关事件埋点,增加web上报调用方法) https://jira.shanqu.cc/browse/GHZS-1629

See merge request halo/android/assistant-android!833
2023-03-22 18:03:21 +08:00
842999ec9d fix: 神策数据埋点第一期--光环助手(修改游戏单相关事件埋点,增加web上报调用方法) https://jira.shanqu.cc/browse/GHZS-1629 2023-03-22 18:03:21 +08:00
fcba306373 fix: 更新畅玩连接服务依赖,修复连接问题 2023-03-22 14:26:29 +08:00
7cb059f1e8 Merge branch 'fix-web_download_delete_error' into 'dev'
fix: 修复网页下载游戏没有正确获取到任务被删除信息的问题

See merge request halo/android/assistant-android!823
2023-03-20 15:19:49 +08:00
78ecde06b1 fix: 修复网页下载游戏没有正确获取到任务被删除信息的问题 2023-03-20 14:49:33 +08:00
44d98090ca Merge branch 'fix-GHZS-1629' into 'dev'
fix: 神策数据埋点第一期--光环助手(修复部分上报数据不准确的问题) https://jira.shanqu.cc/browse/GHZS-1629

See merge request halo/android/assistant-android!820
2023-03-20 10:17:45 +08:00
d7e9b82ef7 fix: 神策数据埋点第一期--光环助手(修复部分上报数据不准确的问题) https://jira.shanqu.cc/browse/GHZS-1629 2023-03-20 10:05:00 +08:00
9345b70c0b Merge branch 'feature-GHZS-1629' into 'dev'
feat: 神策数据埋点第一期--光环助手 https://jira.shanqu.cc/browse/GHZS-1629

See merge request halo/android/assistant-android!818
2023-03-17 16:34:41 +08:00
168e0fff08 feat: 神策数据埋点第一期--光环助手 https://jira.shanqu.cc/browse/GHZS-1629 2023-03-17 16:34:40 +08:00
1af6776356 Merge branch 'fix-home-test-v2-game-filter' into 'dev'
fix:首页-新游开测,优化首页游戏过滤效果,优化下拉刷新效果

See merge request halo/android/assistant-android!817
2023-03-17 11:03:59 +08:00
8340dcb3a0 fix:首页-新游开测,优化首页游戏过滤效果,优化下拉刷新效果 2023-03-17 11:03:58 +08:00
863b6b7970 Merge branch 'fix-GHZS-1663' into 'dev'
fix: 游戏镜像&游戏屏蔽相关优化—0315测试(开服表卡片无法显示问题) https://jira.shanqu.cc/browse/GHZS-1663

See merge request halo/android/assistant-android!816
2023-03-16 22:41:40 +08:00
fb109bab4f Merge branch 'fix-region_settion_error' into 'dev'
fix: 修复区域镜像/屏蔽功能因为接口延迟可能出现的问题

See merge request halo/android/assistant-android!815
2023-03-16 22:31:00 +08:00
fc9bbde996 fix: 游戏镜像&游戏屏蔽相关优化—0315测试(开服表卡片无法显示问题) https://jira.shanqu.cc/browse/GHZS-1663 2023-03-16 22:29:17 +08:00
1c47720561 fix: 修复区域镜像/屏蔽功能因为接口延迟可能出现的问题 2023-03-16 22:27:42 +08:00
8f0bd4e4b5 Merge branch 'fix-GHZS-1673' into 'dev'
fix:首页-新游开测,优化 列表左右滑动的时候,容易触发页面上下滑动 的问题

See merge request halo/android/assistant-android!814
2023-03-16 22:08:01 +08:00
4427523ed9 fix:首页-新游开测,优化 列表左右滑动的时候,容易触发页面上下滑动 的问题 2023-03-16 21:56:14 +08:00
8281d36d69 Merge branch 'fix-GHZS-1668' into 'dev'
fix:首页-新游开测,修复UI间距问题,优化分页逻辑:https://jira.shanqu.cc/browse/GHZS-1668

See merge request halo/android/assistant-android!813
2023-03-16 21:24:20 +08:00
15b2073771 fix:首页-新游开测,修复UI间距问题,优化分页逻辑:https://jira.shanqu.cc/browse/GHZS-1668 2023-03-16 21:24:20 +08:00
c481d99205 Merge branch 'fix-GHZS-1663' into 'dev'
fix: 游戏镜像&游戏屏蔽相关优化—0315测试(补充问题1,2) https://jira.shanqu.cc/browse/GHZS-1663

See merge request halo/android/assistant-android!812
2023-03-16 21:16:10 +08:00
27c4cbd38b fix: 游戏镜像&游戏屏蔽相关优化—0315测试(补充问题1,2) https://jira.shanqu.cc/browse/GHZS-1663 2023-03-16 21:09:25 +08:00
32cb10853c Merge branch 'fix-GHZS-1663' into 'dev'
fix: 游戏镜像&游戏屏蔽相关优化—0315测试(0316测试:1(1)) https://jira.shanqu.cc/browse/GHZS-1663

See merge request halo/android/assistant-android!811
2023-03-16 19:40:46 +08:00
d937fa1953 fix: 游戏镜像&游戏屏蔽相关优化—0315测试(0316测试:1(1)) https://jira.shanqu.cc/browse/GHZS-1663 2023-03-16 19:36:15 +08:00
dc2bcb4699 Merge branch 'fix-GHZS-1173' into 'dev'
fix: OPPO手机拦截安装相关优化(修复弹窗显示异常) https://jira.shanqu.cc/browse/GHZS-1173

See merge request halo/android/assistant-android!810
2023-03-16 18:29:37 +08:00
f514037c48 fix: OPPO手机拦截安装相关优化(修复弹窗显示异常) https://jira.shanqu.cc/browse/GHZS-1173 2023-03-16 18:24:04 +08:00
fcae6fa36c Merge branch 'fix-GHZS-1587' into 'dev'
fix: 畅玩组件安装后自动下载游戏—0310测试(修复初始化时序问题) https://jira.shanqu.cc/browse/GHZS-1587

See merge request halo/android/assistant-android!809
2023-03-16 17:56:55 +08:00
a2594dd700 Merge branch 'fix-GHZS-1637' into 'dev'
fix:首页-新游开测,调整边框颜色和粗细,修复点击最后一个时间轴,小概率会往前移动一个时间轴问题 https://jira.shanqu.cc/browse/GHZS-1637https://jira.shanqu.cc/browse/GHZS-1668

See merge request halo/android/assistant-android!808
2023-03-16 17:53:51 +08:00
8f9fd3a24e fix:首页-新游开测,调整边框颜色和粗细,修复点击最后一个时间轴,小概率会往前移动一个时间轴问题 https://jira.shanqu.cc/browse/GHZS-1637https://jira.shanqu.cc/browse/GHZS-1668 2023-03-16 17:53:50 +08:00
b7da892475 fix: 畅玩组件安装后自动下载游戏—0310测试(修复初始化时序问题) https://jira.shanqu.cc/browse/GHZS-1587 2023-03-16 17:53:05 +08:00
9a68db252e Merge branch 'fix-GHZS-1394' into 'dev'
fix: OPPO手机拦截安装相关优化埋点上报问题 https://jira.shanqu.cc/browse/GHZS-1173

See merge request halo/android/assistant-android!807
2023-03-16 16:13:38 +08:00
5e04e62939 fix: OPPO手机拦截安装相关优化埋点上报问题 https://jira.shanqu.cc/browse/GHZS-1173 2023-03-16 16:08:11 +08:00
403991acc9 Merge branch 'fix-home-test-v2-page' into 'dev'
fix: 调整卡片条目开服日期显示格式,游戏上报字段名称,优化分页逻辑 https://jira.shanqu.cc/browse/GHZS-1637

See merge request halo/android/assistant-android!806
2023-03-16 16:06:20 +08:00
bc21fbcb1a fix: 调整卡片条目开服日期显示格式,游戏上报字段名称,优化分页逻辑 https://jira.shanqu.cc/browse/GHZS-1637 2023-03-16 16:06:20 +08:00
f0dc5a9c83 Merge branch 'fix-GHZS-1669' into 'dev'
fix: 论坛详情页相关优化—0316测试反馈(2-3) https://jira.shanqu.cc/browse/GHZS-1669

See merge request halo/android/assistant-android!805
2023-03-16 15:53:26 +08:00
a170284a3b fix: 论坛详情页相关优化—0316测试反馈(2-3) https://jira.shanqu.cc/browse/GHZS-1669 2023-03-16 15:45:50 +08:00
bd1d300341 Merge branch 'fix-GHZS-1394' into 'dev'
fix: 【光环助手】下载开始埋点上报问题 https://jira.shanqu.cc/browse/GHZS-1394

See merge request halo/android/assistant-android!804
2023-03-16 15:13:15 +08:00
ef29af1aaa fix: 【光环助手】下载开始埋点上报问题 https://jira.shanqu.cc/browse/GHZS-1394 2023-03-16 15:09:16 +08:00
eaf1696a93 Merge branch 'feature-GHZS-1664' into 'dev'
feat: 论坛详情页相关优化—0316优化 https://jira.shanqu.cc/browse/GHZS-1664

See merge request halo/android/assistant-android!803
2023-03-16 14:37:41 +08:00
5ec05a4cb8 feat: 论坛详情页相关优化—0316优化 https://jira.shanqu.cc/browse/GHZS-1664 2023-03-16 14:24:54 +08:00
277acd08eb Merge branch 'fix-GHZS-1587' into 'dev'
fix: 畅玩组件安装后自动下载游戏—0310测试 https://jira.shanqu.cc/browse/GHZS-1587

See merge request halo/android/assistant-android!802
2023-03-16 14:05:23 +08:00
9738269f56 Merge branch 'fix-GHZS-1663' into 'dev'
fix: 游戏镜像&游戏屏蔽相关优化—0315测试 https://jira.shanqu.cc/browse/GHZS-1663

See merge request halo/android/assistant-android!801
2023-03-16 13:50:13 +08:00
13dff229e9 fix: 游戏镜像&游戏屏蔽相关优化—0315测试 https://jira.shanqu.cc/browse/GHZS-1663 2023-03-16 13:45:38 +08:00
8de7e990ac fix: 畅玩组件安装后自动下载游戏—0310测试 https://jira.shanqu.cc/browse/GHZS-1587 2023-03-16 11:56:02 +08:00
97433cd0bd Merge branch 'fix-GHZS-1639' into 'dev'
fix: 游戏镜像&游戏屏蔽相关优化—0314测试-客户端 https://jira.shanqu.cc/browse/GHZS-1639

See merge request halo/android/assistant-android!800
2023-03-15 18:23:58 +08:00
3306db8f68 fix: 游戏镜像&游戏屏蔽相关优化—0314测试-客户端 https://jira.shanqu.cc/browse/GHZS-1639 2023-03-15 18:20:57 +08:00
aabc70d9bb Merge branch 'fix-test-v2-game-filter' into 'dev'
fix-修复测试和UI反馈的问题:https://jira.shanqu.cc/browse/GHZS-1637https://jira.shanqu.cc/browse/GHZS-1641

See merge request halo/android/assistant-android!799
2023-03-15 17:37:46 +08:00
aff9e036cb fix-修复测试和UI反馈的问题:https://jira.shanqu.cc/browse/GHZS-1637https://jira.shanqu.cc/browse/GHZS-1641 2023-03-15 17:37:46 +08:00
e2988cdba6 Merge branch 'fix-low_memory_error' into 'release'
fix: 修改内存不足的时候清空数据造成的闪退问题

See merge request halo/android/assistant-android!798
2023-03-15 16:02:38 +08:00
42c674c1d8 fix: 修改内存不足的时候清空数据造成的闪退问题 2023-03-15 15:59:35 +08:00
dd0962df27 Merge branch 'fix-GHZS-1634' into 'dev'
fix: 论坛详情页相关优化—0315测试-客户端 https://jira.shanqu.cc/browse/GHZS-1634

See merge request halo/android/assistant-android!797
2023-03-15 15:22:57 +08:00
c158be5714 fix: 论坛详情页相关优化—0315测试-客户端 https://jira.shanqu.cc/browse/GHZS-1634 2023-03-15 15:12:48 +08:00
ee6ec82d27 Merge branch 'fix-GHZS-1622' into 'dev'
fix: OPPO手机拦截安装相关优化—0314测试 (更正接口调用) https://jira.shanqu.cc/browse/GHZS-1622

See merge request halo/android/assistant-android!796
2023-03-15 09:24:07 +08:00
317cce1f56 fix: OPPO手机拦截安装相关优化—0314测试 (更正接口调用) https://jira.shanqu.cc/browse/GHZS-1622 2023-03-14 18:31:10 +08:00
f29f5089fd Merge branch 'feature-GHZS-1216' into 'dev'
feat:【光环助手】实名认证接口崩溃预案  https://jira.shanqu.cc/browse/GHZS-1216

See merge request halo/android/assistant-android!795
2023-03-14 18:06:49 +08:00
f5b71fdcb2 feat:【光环助手】实名认证接口崩溃预案 https://jira.shanqu.cc/browse/GHZS-1216 2023-03-14 18:03:45 +08:00
79c0e61a24 Merge branch 'feature-GHZS-1576' into 'dev'
feat: 游戏专题相关功能优化—客户端(补充下载完成的广告曝光埋点) https://jira.shanqu.cc/browse/GHZS-1576

See merge request halo/android/assistant-android!794
2023-03-14 17:50:50 +08:00
bfeadf8c75 feat: 游戏专题相关功能优化—客户端(补充下载完成的广告曝光埋点) https://jira.shanqu.cc/browse/GHZS-1576 2023-03-14 17:23:36 +08:00
b118309d4e Merge branch 'feature-GHZS-1498' into 'dev'
feat: 论坛详情页相关优化—客户端 https://jira.shanqu.cc/browse/GHZS-1498

See merge request halo/android/assistant-android!792
2023-03-14 15:59:39 +08:00
5aab516058 feat: 论坛详情页相关优化—客户端 https://jira.shanqu.cc/browse/GHZS-1498 2023-03-14 15:59:38 +08:00
3ef4214313 Merge branch 'fix-GHZS-1611' into 'dev'
fix: 游戏镜像&游戏屏蔽相关优化—0314测试-后端(3(2)) https://jira.shanqu.cc/browse/GHZS-1611

See merge request halo/android/assistant-android!793
2023-03-14 15:57:20 +08:00
dcca1b9ff9 fix: 游戏镜像&游戏屏蔽相关优化—0314测试-后端(3(2)) https://jira.shanqu.cc/browse/GHZS-1611 2023-03-14 15:53:26 +08:00
905b6395d7 Merge branch 'hotfix-v5.21.0-770-change_sensor_scheme' into 'release'
feat: 限制神策 SDK 渠道,日志上报稳定前先上报到测试项目,添加全局开关 https://jira.shanqu.cc/browse/GHZS-1613

See merge request halo/android/assistant-android!791
2023-03-14 14:31:24 +08:00
7bdc7a946d Merge branch 'fix-change-debug-log-class' into 'dev'
fix:更换新游开测使用的debug日志类。并补充新游开测需求地址:https://jira.shanqu.cc/browse/GHZS-1351

See merge request halo/android/assistant-android!790
2023-03-14 14:26:44 +08:00
55a92847c7 fix:更换新游开测使用的debug日志类。并补充新游开测需求地址:https://jira.shanqu.cc/browse/GHZS-1351 2023-03-14 14:26:44 +08:00
0889abef9e feat: 限制神策 SDK 渠道,日志上报稳定前先上报到测试项目,添加全局开关 https://jira.shanqu.cc/browse/GHZS-1613 2023-03-14 14:18:11 +08:00
b858365c1d Merge branch 'feat-GHZS-1351' into 'dev'
feat:首页/板块-新游开测-开发完成

See merge request halo/android/assistant-android!788
2023-03-14 14:00:57 +08:00
92d2f7e701 feat:首页/板块-新游开测-开发完成 2023-03-14 14:00:57 +08:00
0967df5751 Merge branch 'feature-GHZS-1492' into 'dev'
feat: 镜像游戏-游戏更新优化—客户端 https://jira.shanqu.cc/browse/GHZS-1492

See merge request halo/android/assistant-android!789
2023-03-14 12:03:47 +08:00
d6e5b88d95 Merge remote-tracking branch 'origin/dev' into dev-5.22.0 2023-03-13 17:47:57 +08:00
b08e653b99 Merge remote-tracking branch 'origin/release' into dev
# Conflicts:
#	dependencies.gradle
#	module_common/src/main/java/com/gh/gamecenter/common/view/MaxHeightLinearLayout.kt
2023-03-13 17:41:10 +08:00
f539e45e18 feat: 镜像游戏-游戏更新优化—客户端 https://jira.shanqu.cc/browse/GHZS-1492 2023-03-13 15:50:49 +08:00
6a6ff5b12a ci: 调整最大 JVM heap size,避免编译时 OOM 2023-03-13 14:57:41 +08:00
b8ba5f85c9 Merge branch 'fix-GHZS-1587' into 'dev-5.22.0'
fix: 畅玩组件安装后自动下载游戏—0310测试 https://jira.shanqu.cc/browse/GHZS-1587

See merge request halo/android/assistant-android!787
2023-03-13 11:41:25 +08:00
67ed3cb919 fix: 畅玩组件安装后自动下载游戏—0310测试 https://jira.shanqu.cc/browse/GHZS-1587 2023-03-13 11:37:20 +08:00
c973bd6b5e Merge branch 'fix-GHZS-1591' into 'dev-5.22.0'
fix: 游戏专题新增[视频横屏滑动]样式—0313UI测试 https://jira.shanqu.cc/browse/GHZS-1591

See merge request halo/android/assistant-android!786
2023-03-13 11:29:10 +08:00
61e9bcb89d fix: 游戏专题新增[视频横屏滑动]样式—0313UI测试 https://jira.shanqu.cc/browse/GHZS-1591 2023-03-13 11:27:23 +08:00
2d3f18a302 Merge branch 'fix-vpn_setting_null_pointer' into 'dev-5.22.0'
fix: 修复安装配置为空时的空指针异常

See merge request halo/android/assistant-android!785
2023-03-13 11:17:50 +08:00
401d36a74e fix: 修复安装配置为空时的空指针异常 2023-03-13 11:15:36 +08:00
bee52ba0bd Merge branch 'feature-GHZS-1343' into 'dev-5.22.0'
fix: 【光环助手】OPPO手机拦截安装相关优化 https://jira.shanqu.cc/browse/GHZS-1343

See merge request halo/android/assistant-android!784
2023-03-13 11:01:02 +08:00
6d2e0853ff feat: 【光环助手】OPPO手机拦截安装相关优化 https://jira.shanqu.cc/browse/GHZS-1343 2023-03-13 11:01:02 +08:00
3b23f086c8 Merge branch 'fix-GHZS-1544' into 'dev-5.22.0'
fix: 【光环助手】游戏详情滑动问题 https://jira.shanqu.cc/browse/GHZS-1544

See merge request halo/android/assistant-android!783
2023-03-10 11:42:58 +08:00
d50e4e044b fix: 【光环助手】游戏详情滑动问题 https://jira.shanqu.cc/browse/GHZS-1544 2023-03-10 11:40:08 +08:00
84f56681d0 Merge remote-tracking branch 'origin/dev' into dev-5.22.0 2023-03-10 10:52:41 +08:00
7fbb3eec86 Merge branch 'feature-GHZS-1287' into 'dev-5.22.0'
feat: 游戏专题新增[视频横屏滑动]样式—客户端 https://jira.shanqu.cc/browse/GHZS-1287

See merge request halo/android/assistant-android!782
2023-03-09 15:55:11 +08:00
ef11044b50 feat: 游戏专题新增[视频横屏滑动]样式—客户端 https://jira.shanqu.cc/browse/GHZS-1287 2023-03-09 15:55:11 +08:00
26395038bd Merge branch 'feature-GHZS-1528' into 'dev-5.22.0'
fix: 【光环助手】畅玩组件安装后自动下载游戏 https://jira.shanqu.cc/browse/GHZS-1516

See merge request halo/android/assistant-android!781
2023-03-09 09:47:34 +08:00
68b0691618 fix: 【光环助手】畅玩组件安装后自动下载游戏 https://jira.shanqu.cc/browse/GHZS-1516 2023-03-09 09:36:32 +08:00
f5a4e4ca06 Merge branch 'fix-GHZS-1543' into 'dev-5.22.0'
fix: 启动广告图显示错误—0306测试 https://jira.shanqu.cc/browse/GHZS-1543

See merge request halo/android/assistant-android!780
2023-03-08 16:52:43 +08:00
c75eacaf45 fix: 启动广告图显示错误—0306测试 https://jira.shanqu.cc/browse/GHZS-1543 2023-03-08 16:37:09 +08:00
aa5ecb8e6c Merge branch 'feature-GHZS-1550' into 'dev-5.22.0'
fix: 游戏镜像&游戏屏蔽相关优化—客户端 https://jira.shanqu.cc/browse/GHZS-1550

See merge request halo/android/assistant-android!779
2023-03-08 09:30:56 +08:00
00dda64279 Merge branch 'fix-GHZS-1549' into 'dev-5.22.0'
fix: 新增用户-用户短ID显示优化—0307测试 https://jira.shanqu.cc/browse/GHZS-1549

See merge request halo/android/assistant-android!778
2023-03-08 09:20:34 +08:00
2bd3be0088 fix: 新增用户-用户短ID显示优化—0307测试 https://jira.shanqu.cc/browse/GHZS-1549 2023-03-07 21:39:15 +08:00
3bff64af27 fix: 游戏镜像&游戏屏蔽相关优化—客户端 https://jira.shanqu.cc/browse/GHZS-1550 2023-03-07 21:15:51 +08:00
32210875da chore: 版本更新至 5.19.5 2023-03-07 17:36:38 +08:00
db9d7d9d22 Merge branch 'merge_dev_to_release' into 'release'
合并 dev 部分修改到 release 分支

See merge request halo/android/assistant-android!777
2023-03-07 17:29:25 +08:00
1f211356fd fix:【光环助手】资讯文章-下载按钮显示问题(0206测试1) https://jira.shanqu.cc/browse/GHZS-1066 2023-03-07 17:20:10 +08:00
81b5b6b369 fix:【光环助手】资讯文章-下载按钮显示问题 https://jira.shanqu.cc/browse/GHZS-1066 2023-03-07 17:20:07 +08:00
98e263f99a fix:【光环助手】多版本下载面板-版本说明显示问题 https://jira.shanqu.cc/browse/GHZS-1064 2023-03-07 17:19:55 +08:00
81b74e7077 Merge branch 'feature-GHZS-1484' into 'dev-5.22.0'
feat: 游戏搜素-内容标签点击优化—客户端 https://jira.shanqu.cc/browse/GHZS-1484

See merge request halo/android/assistant-android!775
2023-03-07 16:42:35 +08:00
083a893582 feat: 游戏搜素-内容标签点击优化—客户端 https://jira.shanqu.cc/browse/GHZS-1484 2023-03-07 16:42:35 +08:00
405d4b709f Merge branch 'feature-GHZS-1491' into 'dev-5.22.0'
feat: 多版本下载面板优化—客户端 https://jira.shanqu.cc/browse/GHZS-1491

See merge request halo/android/assistant-android!776
2023-03-07 16:41:58 +08:00
36942aab5a feat: 多版本下载面板优化—客户端 https://jira.shanqu.cc/browse/GHZS-1491 2023-03-07 16:04:45 +08:00
e61b21ca49 Merge branch 'fix-dark_mode' into 'dev'
fix: 修复切换深色模式首页游戏没有更新颜色的问题

See merge request halo/android/assistant-android!774
2023-03-07 15:21:37 +08:00
b9e7f4145a fix: 修复切换深色模式首页游戏没有更新颜色的问题 2023-03-07 15:21:37 +08:00
517b474a1e Merge branch 'fix-GHZS-1440' into 'dev'
fix: 【光环助手】游戏专题夜间模式显示问题 https://jira.shanqu.cc/browse/GHZS-1440

See merge request halo/android/assistant-android!773
2023-03-07 14:24:28 +08:00
dfac1e93b7 fix: 【光环助手】游戏专题夜间模式显示问题 https://jira.shanqu.cc/browse/GHZS-1440 2023-03-07 14:02:02 +08:00
d848081f62 Merge branch 'fix-typo' into 'dev'
fix: 更正用户 id 和 gid 的命名

See merge request halo/android/assistant-android!772
2023-03-07 10:49:04 +08:00
2bac0feb2c fix: 更正用户 id 和 gid 的命名 2023-03-07 10:44:48 +08:00
a602055f98 Merge branch 'hotfix-v5.19.4-734-vector_crash' into 'release'
fix: 修复5.0以下系统矢量图相关闪退问题

See merge request halo/android/assistant-android!771
2023-03-07 10:11:00 +08:00
28ba14e9ec Merge branch 'feature-GHZS-1419' into 'dev'
feat: 神策埋点接入测试--光环埋点 https://jira.shanqu.cc/browse/GHZS-1419

See merge request halo/android/assistant-android!770
2023-03-07 09:31:20 +08:00
c36fb04f81 feat: 神策埋点接入测试--光环埋点 https://jira.shanqu.cc/browse/GHZS-1419 2023-03-07 09:21:04 +08:00
7d26a66bc3 Merge remote-tracking branch 'origin/dev' into dev-5.22.0 2023-03-06 19:57:30 +08:00
9451f9bae3 Merge remote-tracking branch 'origin/release' into dev
# Conflicts:
#	dependencies.gradle
2023-03-06 19:55:40 +08:00
ac18a678ff Merge remote-tracking branch 'origin/legacy-release' into release
# Conflicts:
#	app/proguard-rules.txt
2023-03-06 19:55:05 +08:00
bd2871788f fix: 修复5.0以下系统矢量图相关闪退问题 2023-03-06 17:16:58 +08:00
beeece1d0e Merge branch 'feature-GHZS-1417' into 'dev'
feat: 神策埋点接入测试--SDK接入 https://jira.shanqu.cc/browse/GHZS-1417

See merge request halo/android/assistant-android!769
2023-03-06 16:10:51 +08:00
1e9e39eea9 feat: 神策埋点接入测试--SDK接入 https://jira.shanqu.cc/browse/GHZS-1417 2023-03-06 16:10:51 +08:00
9162b0f67d Merge branch 'fix-news_js_error' into 'dev'
fix: 修复新闻资讯页因为没有设置 PageFinishListener 导致的方法调用问题

See merge request halo/android/assistant-android!768
2023-03-06 11:49:38 +08:00
46dd84aaf9 fix: 修复新闻资讯页因为没有设置 PageFinishListener 导致的方法调用问题 2023-03-06 11:46:24 +08:00
e5e0d99abb Merge branch 'feature-GHZS-1428' into 'dev-5.22.0'
fix: 【光环助手】游戏详情-游戏礼包显示问题 https://jira.shanqu.cc/browse/GHZS-1428

See merge request halo/android/assistant-android!767
2023-03-06 09:09:29 +08:00
6f34b16bba fix: 【光环助手】游戏详情-游戏礼包显示问题 https://jira.shanqu.cc/browse/GHZS-1428 2023-03-03 21:09:13 +08:00
5b2512f16f Merge branch 'feature-GHZS-1537' into 'dev-5.22.0'
fix: 新增用户-用户短ID显示优化—客户端 https://jira.shanqu.cc/browse/GHZS-1537

See merge request halo/android/assistant-android!766
2023-03-03 18:42:07 +08:00
9a1e0f1ae2 fix: 新增用户-用户短ID显示优化—客户端 https://jira.shanqu.cc/browse/GHZS-1537 2023-03-03 18:34:10 +08:00
a03b6b643f Merge branch 'fix-GHZS-1539' into 'dev-5.22.0'
fix: 修复缓存的启动广告图过期仍显示的问题 https://jira.shanqu.cc/browse/GHZS-1539

See merge request halo/android/assistant-android!765
2023-03-03 16:36:59 +08:00
8b2cb8b40c fix: 修复缓存的启动广告图过期仍显示的问题 https://jira.shanqu.cc/browse/GHZS-1539 2023-03-03 16:32:43 +08:00
c2402bd4d2 Merge branch 'feature-GHZS-1490' into 'dev-5.22.0'
fix: 游戏详情-顶部视频播放优化—客户端 https://jira.shanqu.cc/browse/GHZS-1490

See merge request halo/android/assistant-android!764
2023-03-03 15:53:22 +08:00
b724cde6ca fix: 游戏详情-顶部视频播放优化—客户端 https://jira.shanqu.cc/browse/GHZS-1490 2023-03-03 15:53:22 +08:00
fd3058e0be Merge branch 'fix-gdt' into 'legacy-release'
fix: 修改广点通默认数据源id和密钥

See merge request halo/android/assistant-android!762
2023-03-03 11:12:58 +08:00
03431ef3a3 Merge branch 'feature-GHZS-1502' into 'dev-5.22.0'
fix: 新增GIF图片可点击关闭—客户端 https://jira.shanqu.cc/browse/GHZS-1502

See merge request halo/android/assistant-android!761
2023-03-03 09:51:08 +08:00
23e2a79bee fix: 新增GIF图片可点击关闭—客户端 https://jira.shanqu.cc/browse/GHZS-1502 2023-03-03 09:40:06 +08:00
3aa14c9541 chore: 版本更新为 5.22.0 2023-03-02 17:54:57 +08:00
39fcc5ed63 Merge branch 'fix-GHZS-1448' into 'dev-5.21.0'
fix: 游戏礼包新增兑换码功能—0228测试-客户端部分-客户端 https://jira.shanqu.cc/browse/GHZS-1448

See merge request halo/android/assistant-android!760
2023-03-02 16:53:12 +08:00
577be922a6 fix: 游戏礼包新增兑换码功能—0228测试-客户端部分-客户端 https://jira.shanqu.cc/browse/GHZS-1448 2023-03-02 16:48:38 +08:00
19d128e98a Merge branch 'fix-typo' into 'dev-5.21.0'
fix: 更新畅玩提示文案

See merge request halo/android/assistant-android!759
2023-03-02 16:45:42 +08:00
a8acf1d6c8 fix: 更新畅玩提示文案 2023-03-02 16:44:06 +08:00
ce0a301348 Merge branch 'fix-GHZS-1485' into 'dev-5.21.0'
fix: 多版本游戏下载按钮显示问题—客户端 https://jira.shanqu.cc/browse/GHZS-1485

See merge request halo/android/assistant-android!758
2023-03-02 15:06:01 +08:00
2567e520da fix: 多版本游戏下载按钮显示问题—客户端 https://jira.shanqu.cc/browse/GHZS-1485 2023-03-02 14:57:02 +08:00
2394cf837e Merge branch 'fix-GHZS-1450' into 'dev-5.21.0'
fix: 用户更换头像功能优化—0301UI测试(第3点、添加头像边框) https://jira.shanqu.cc/browse/GHZS-1450

See merge request halo/android/assistant-android!757
2023-03-02 11:41:14 +08:00
bf692569e6 fix: 用户更换头像功能优化—0301UI测试(第3点、添加头像边框) https://jira.shanqu.cc/browse/GHZS-1450 2023-03-02 11:36:09 +08:00
090102ec5d Merge branch 'fix-GHZS-1425' into 'dev-5.21.0'
fix: 副标题前端显示优化—0228测试(修复无副标题时广告标识不显示的问题) https://jira.shanqu.cc/browse/GHZS-1425

See merge request halo/android/assistant-android!756
2023-03-02 09:57:16 +08:00
61e9966de8 fix: 副标题前端显示优化—0228测试(修复无副标题时广告标识不显示的问题) https://jira.shanqu.cc/browse/GHZS-1425 2023-03-02 09:24:44 +08:00
fe26504f43 Merge branch 'fix-video_callback_error' into 'dev-5.21.0'
fix: 修复帖子详情页的网页视频进度同步异常

See merge request halo/android/assistant-android!755
2023-03-01 19:21:40 +08:00
e4d2036cc2 chore: 版本更新至 5.19.4 2023-03-01 19:12:38 +08:00
2627a4c39c fix: 调整方法实现 2023-03-01 19:08:48 +08:00
a44d454f13 fix: 修复帖子详情页的网页视频进度同步异常 2023-03-01 18:07:35 +08:00
0600daadde Merge branch 'feature-add_download_header' into 'release'
feat: 添加新的 download header 供后端接口使用

See merge request halo/android/assistant-android!752
2023-03-01 17:55:07 +08:00
f29b1a6124 Merge branch 'fix-GHZS-1450' into 'dev-5.21.0'
fix: 用户更换头像功能优化—0301UI测试 https://jira.shanqu.cc/browse/GHZS-1450

See merge request halo/android/assistant-android!754
2023-03-01 15:41:56 +08:00
1892d10040 Merge branch 'fix-GHZS-1425' into 'dev-5.21.0'
fix: 副标题前端显示优化—0228测试 https://jira.shanqu.cc/browse/GHZS-1425

See merge request halo/android/assistant-android!753
2023-03-01 15:16:24 +08:00
9a8df13870 fix: 用户更换头像功能优化—0301UI测试 https://jira.shanqu.cc/browse/GHZS-1450 2023-03-01 15:14:11 +08:00
4eabeae5d5 fix: 副标题前端显示优化—0228测试 https://jira.shanqu.cc/browse/GHZS-1425 2023-03-01 14:34:05 +08:00
c4b1be9925 feat: 添加新的 download header 供后端接口使用 2023-03-01 13:43:37 +08:00
b2a6393afd Merge branch 'hotfix-v5.19.3-733-vspace_update_issue' into 'release'
fix: 修复畅玩组件更新后因为服务连接延迟导致的游戏游戏状态显示异常

See merge request halo/android/assistant-android!750
2023-03-01 13:38:46 +08:00
b5c15940a1 Merge branch 'hotfix-v5.19.3-733-archive_tab_error' into 'release'
fix: 修复游戏详情隐藏专区 tab 且显示云存档 tab 时,云存档红点错位的问题

See merge request halo/android/assistant-android!751
2023-03-01 13:38:01 +08:00
3f6f55b265 fix: 修复畅玩组件更新后因为服务连接延迟导致的游戏游戏状态显示异常 2023-03-01 11:19:27 +08:00
ba666da059 fix: 修复游戏详情隐藏专区 tab 且显示云存档 tab 时,云存档红点错位的问题 2023-03-01 11:16:33 +08:00
8b1f251c80 Merge remote-tracking branch 'origin/dev' into dev-5.21.0 2023-02-28 19:18:52 +08:00
01aadbd64c Merge remote-tracking branch 'origin/release' into dev
# Conflicts:
#	dependencies.gradle
2023-02-28 19:17:48 +08:00
6256b31cd9 Merge branch 'fix-ultra_short_device_display_issue' into 'dev-5.21.0'
fix: 修复部分设备使用 applicationContext 无法获取到实时 window 高度的问题

See merge request halo/android/assistant-android!749
2023-02-28 17:43:20 +08:00
8e4d1e7e6e fix: 修复部分设备使用 applicationContext 无法获取到实时 window 高度的问题 2023-02-28 17:34:28 +08:00
fa29e00864 Merge branch 'hotfix-v5.19.3-733-gamedetail_tab' into 'release'
fix: 修复游戏详情页超过 3 个 tab 时,页面变空白的问题

See merge request halo/android/assistant-android!748
2023-02-28 16:27:36 +08:00
1b412bf081 fix: 修复游戏详情页超过 3 个 tab 时,页面变空白的问题 2023-02-28 16:13:52 +08:00
0d82b9ec71 Merge branch 'feature-GHZS-1342' into 'dev-5.21.0'
feat: 帖子详情页视频播放优化 https://jira.shanqu.cc/browse/GHZS-1342

See merge request halo/android/assistant-android!747
2023-02-28 15:43:01 +08:00
1055d0c728 feat: 帖子详情页视频播放优化 https://jira.shanqu.cc/browse/GHZS-1342 2023-02-28 15:43:01 +08:00
a53183d405 Merge branch 'feature-GHZS-1304' into 'dev-5.21.0'
feat: 用户更换头像功能优化—客户端 https://jira.shanqu.cc/browse/GHZS-1304

See merge request halo/android/assistant-android!745
2023-02-28 15:07:52 +08:00
11874c3984 fix: 更换默认头像确认后添加正在修改dialog,修复更换默认头像后没有关闭所有弹窗的问题 2023-02-28 15:07:16 +08:00
47464b2864 Merge branch 'fix-GHZS-1422' into 'dev-5.21.0'
fix: 游戏专题-双列卡片 动图加载优化—0228测试 https://jira.shanqu.cc/browse/GHZS-1422

See merge request halo/android/assistant-android!746
2023-02-28 14:14:07 +08:00
a2ed4987ed Merge branch 'feature-GHZS-1300' into 'dev-5.21.0'
feat: 游戏礼包新增兑换码功能 https://jira.shanqu.cc/browse/GHZS-1300

See merge request halo/android/assistant-android!744
2023-02-28 14:06:58 +08:00
4392f9f20b feat: 游戏礼包新增兑换码功能 https://jira.shanqu.cc/browse/GHZS-1300 2023-02-28 14:06:57 +08:00
8e43d0cae3 Merge branch 'dev-5.21.0' into feature-GHZS-1304
# Conflicts:
#	app/src/main/java/com/gh/common/util/NewFlatLogUtils.kt
2023-02-28 14:06:34 +08:00
f83f67553c feat: 用户更换头像功能优化—客户端(数据埋点) https://jira.shanqu.cc/browse/GHZS-1304 2023-02-28 14:02:19 +08:00
14893acf4b fix: 游戏专题-双列卡片 动图加载优化—0228测试 https://jira.shanqu.cc/browse/GHZS-1422 2023-02-28 13:44:30 +08:00
1cbed03788 Merge branch 'feature-GHZS-1312' into 'dev-5.21.0'
fix: 跳转链接通用模块新增[发现页]—客户端 https://jira.shanqu.cc/browse/GHZS-1312

See merge request halo/android/assistant-android!743
2023-02-28 11:46:09 +08:00
0eff89acfc fix: 跳转链接通用模块新增[发现页]—客户端 https://jira.shanqu.cc/browse/GHZS-1312 2023-02-28 11:40:28 +08:00
560b6046ab Merge branch 'feature-GHZS-1307' into 'dev-5.21.0'
feat: 副标题前端显示优化—客户端 https://jira.shanqu.cc/browse/GHZS-1307

See merge request halo/android/assistant-android!740
2023-02-28 09:56:58 +08:00
e898886659 feat: 副标题前端显示优化—客户端 https://jira.shanqu.cc/browse/GHZS-1307 2023-02-28 09:56:58 +08:00
b1abadc145 chore: 版本更新至 5.19.3 2023-02-27 16:21:22 +08:00
05da2c3da4 Merge branch 'hotfix-v5.19.2-732-crashes' into 'release'
fix: 修复闪退

See merge request halo/android/assistant-android!742
2023-02-27 15:35:18 +08:00
e83ece5520 fix: 捕抓游戏详情页上报视频相关日志时的闪退 https://sentry.shanqu.cc/organizations/lightgame/issues/272842/?project=22&query=release%3Acom.gh.gamecenter%405.19.2%2B732+error.unhandled%3Atrue&sort=freq 2023-02-27 15:26:59 +08:00
08a86c778d fix: 修复游戏详情延迟选中时的闪退 https://sentry.shanqu.cc/organizations/lightgame/issues/272842/?project=22&query=release%3Acom.gh.gamecenter%405.19.2%2B732+error.unhandled%3Atrue&sort=freq 2023-02-27 14:57:03 +08:00
58119a0bdb Merge branch 'feature-GHZS-1293' into 'dev-5.21.0'
feat: 游戏详情-置顶标签功能—客户端 https://jira.shanqu.cc/browse/GHZS-1293

See merge request halo/android/assistant-android!741
2023-02-27 09:55:20 +08:00
8d9c57e972 feat: 游戏详情-置顶标签功能—客户端 https://jira.shanqu.cc/browse/GHZS-1293 2023-02-27 09:55:20 +08:00
b216d33d6b chore: 版本更新至 5.19.2 2023-02-24 16:00:21 +08:00
4fe062ea40 Merge branch 'feature-GHZS-1386' into 'release'
feat: 启动畅玩游戏时添加光环版本和渠道 https://jira.shanqu.cc/browse/GHZS-1386

See merge request halo/android/assistant-android!739
2023-02-24 11:14:43 +08:00
7d678085d5 feat: 启动畅玩游戏时添加光环版本和渠道 https://jira.shanqu.cc/browse/GHZS-1386 2023-02-24 11:09:57 +08:00
acae755461 Merge branch 'fix-add_direct_link_type' into 'dev'
fix: 添加新游开测跳转链接类型 https://jira.shanqu.cc/browse/GHZS-1127

See merge request halo/android/assistant-android!738
2023-02-23 17:39:27 +08:00
f29d3b4e29 fix: 添加新游开测跳转链接类型 https://jira.shanqu.cc/browse/GHZS-1127 2023-02-23 17:37:05 +08:00
e1907fcea8 fix: 修改广点通默认数据源id和密钥 2023-02-23 15:46:22 +08:00
76564b2414 feat: 用户更换头像功能优化—客户端 https://jira.shanqu.cc/browse/GHZS-1304 2023-02-21 14:57:05 +08:00
c72d34b4f7 Merge branch 'fix-gdt_permission' into 'legacy-release'
fix: 广点通打包时恢复READ_PHONE_STATE权限

See merge request halo/android/assistant-android!727
2023-02-20 14:51:28 +08:00
8145f389a9 fix: 广点通打包时恢复READ_PHONE_STATE权限 2023-02-20 14:45:00 +08:00
45a8f9683e Merge branch 'feature-GHZS-1254' into 'legacy-release'
feat: 对接广点通SDK—客户端 https://jira.shanqu.cc/browse/GHZS-1254

See merge request halo/android/assistant-android!711
2023-02-16 11:41:01 +08:00
572cbba819 feat: 对接广点通SDK—客户端 https://jira.shanqu.cc/browse/GHZS-1254 2023-02-16 11:41:00 +08:00
413 changed files with 12103 additions and 2468 deletions

View File

@ -1,12 +1,57 @@
stages:
- analysis
- sendmail
- android-build && analysis
- docker-build && sendmail
- deploy-trigger
## 代码检查
android_build:
tags:
- offline-test
stage: android-build && analysis
image: hub.shanqu.cc/devops/ci-android:jdk11
variables:
KUBERNETES_CPU_LIMIT: "16"
GIT_SUBMODULE_STRATEGY: recursive
Apk_Path: "app/build/outputs/apk/**/release/*.apk"
script:
- export GRADLE_USER_HOME=./.gradle
- chmod +x ./gradlew
- ./scripts/meta_build.sh --config_id 6400549c21c2c94ead074500 --sdk_platform toutiao --sdk_version 5.3.0 --channel BD-GHZS-ZP-KY --activate_reporting_ratio 60 --first_lanuch_jump e1wibGlua190eXBlXCI6XCJcIixcImxpbmtfaWRcIjpcIlwiLFwibGlua190ZXh0XCI6XCJcIixcImhvbWVfaW5kZXhcIjpcIlwiLFwiYm90dG9tX2luZGV4XCI6XCJcIn0= --unix_timestamp 1677657618 --output ./release/com.gh.gamecenter_5.17.4_694_BD-GHZS-ZP-KY_toutiao_5.3.0_1677657618.apk
- rm -rf ./.gradle/caches/build-cache-1
cache:
paths:
- .gradle
artifacts:
paths:
- Dockerfile
expire_in: 15 mins
only:
- feature-meta_build
# 构建推送docker镜像
docker-build:
tags:
- offline-test
stage: docker-build && sendmail
image: hub.shanqu.cc/library/docker:latest
variables:
GIT_STRATEGY: none
script:
- projectPath=`echo $CI_PROJECT_PATH | sed 's#/#-#g'`
- docker build -t registry.cn-shenzhen.aliyuncs.com/ghzs/$projectPath:latest .
- docker push registry.cn-shenzhen.aliyuncs.com/ghzs/$projectPath:latest
- docker run -e PROJECTKEY=$projectPath -e EMAIL=$GITLAB_USER_EMAIL -e BRANCH=$CI_COMMIT_REF_NAME --name send-email --rm hub.shanqu.cc/platform/send-sonar-report:latest
cache:
paths:
- .gradle
policy: pull
only:
- feature-meta_build
# 代码检查
sonarqube_analysis:
tags:
- offline-test
stage: analysis
stage: android-build && analysis
image: sonarsource/sonar-scanner-cli:latest
dependencies: [] #禁止传递来的artifact
script:
@ -27,17 +72,12 @@ sonarqube_analysis:
-Dsonar.gitlab.merge_request_discussion=true
-Dsonar.java.binaries=. # 如果不使用Maven或Gradle进行分析则必须手动提供测试二进制文件
only:
- dev
## 发送简易检测结果报告
send_sonar_report:
tags:
- offline-test
stage: sendmail
image: hub.shanqu.cc/library/docker:latest
dependencies: [] #禁止传递来的artifact
script:
- group=`echo $CI_PROJECT_PATH | sed 's#/#-#g'`
- docker run -e PROJECTKEY=$group -e EMAIL=$GITLAB_USER_EMAIL --name send-email --rm hub.shanqu.cc/platform/send-sonar-report:latest
only:
- dev
- feature-meta_build
## 触发多项目构建
trigger_job:
stage: deploy-trigger
trigger:
project: devops/automation/build-eci
branch: dev

8
.gitmodules vendored
View File

@ -1,13 +1,13 @@
[submodule "libraries/LGLibrary"]
path = libraries/LGLibrary
url = git@git.shanqu.cc:android/common-library.git
url = ../../../android/common-library.git
branch = master
[submodule "vspace-bridge"]
path = vspace-bridge
url = git@git.shanqu.cc:cwzs/android/vspace-bridge.git
url = ../../../cwzs/android/vspace-bridge.git
[submodule "module_common/src/debug/assets/assistant-android-mock"]
path = module_common/src/debug/assets/assistant-android-mock
url = git@git.shanqu.cc:halo/android/assistant-android-mock.git
url = ../../../halo/android/assistant-android-mock.git
[submodule "ndownload"]
path = ndownload
url = git@git.shanqu.cc:android/ndownload.git
url = ../../../android/ndownload.git

15
Dockerfile Normal file
View File

@ -0,0 +1,15 @@
FROM openjdk:11-jdk
WORKDIR /project
SHELL ["/bin/bash", "-c"]
#配置SDK环境变量
ENV ANDROID_SDK_ROOT /usr/lib/sdk
ENV ANDROID_HOME /usr/lib/sdk
ENV PATH $ANDROID_SDK_ROOT:$PATH
ENV PATH=$PATH:${ANDROID_HOME}/cmdline-tools/cmdline-tools/bin/
ENV GRADLE_USER_HOME /project/.gradle
RUN source ~/.bashrc
RUN sed -i "s@http://\(deb\|security\).debian.org@https://mirrors.aliyun.com@g" /etc/apt/sources.list \
&& apt-get --quiet update --yes \
&& apt-get --quiet install --yes lib32stdc++6 lib32z1 libncurses5 util-linux bash tzdata librdkafka-dev pkgconf \
&& rm -rf /var/lib/apt/lists/*
COPY .gradle /project/.gradle

View File

@ -9,6 +9,9 @@ import groovy.xml.XmlUtil
android {
String CONFIG_ID = ""
String FIRST_LAUNCH = ""
buildFeatures {
viewBinding true
dataBinding true
@ -67,9 +70,13 @@ android {
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt', 'proguard-fresco.txt'
/**
* All third-party appid/appkey
*/
// 推广用的配置 id
buildConfigField "String", "CONFIG_ID", "\"${CONFIG_ID}\""
// 首次启动的跳转配置
buildConfigField "String", "FIRST_LAUNCH", "\"${FIRST_LAUNCH}\""
// All third-party appid/appkey
buildConfigField "String", "API_HOST", "\"${API_HOST}\""
buildConfigField "String", "NEW_API_HOST", "\"${NEW_API_HOST}\""
buildConfigField "String", "VAPI_HOST", "\"${VAPI_HOST}\""
@ -127,7 +134,7 @@ android {
variantFilter { variant ->
def names = variant.flavors*.name
def isDebugType = variant.buildType.name == "debug"
if ((names.contains("tea") || name.contains("kuaishou")) && isDebugType) {
if ((names.contains("tea") || name.contains("kuaishou") || name.contains("gdt")) && isDebugType) {
setIgnore(true)
}
}
@ -147,6 +154,9 @@ android {
kuaishou {
java.srcDirs = ['src/main/java', 'src/kuaishou/java']
}
gdt {
java.srcDirs = ['src/main/java', 'src/gdt/java']
}
}
productFlavors {
@ -194,6 +204,16 @@ android {
buildConfigField "String", "QUICK_LOGIN_APPID", "\"${QUICK_LOGIN_APPID}\""
buildConfigField "String", "QUICK_LOGIN_APPKEY", "\"${QUICK_LOGIN_APPKEY}\""
}
gdt {
dimension "env"
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}\""
}
}
}
@ -209,6 +229,7 @@ dependencies {
teaImplementation fileTree(include: ['*.jar', '*.aar'], dir: 'src/tea/libs')
kuaishouImplementation fileTree(include: ['*.jar', '*.aar'], dir: 'src/kuaishou/libs')
gdtImplementation fileTree(include: ['*.jar', '*.aar'], dir: 'src/gdt/libs')
testImplementation 'junit:junit:4.12'
debugImplementation "com.squareup.leakcanary:leakcanary-android:${leakcanary}"
@ -216,8 +237,7 @@ dependencies {
// debugImplementation "com.gu.android:toolargetool:${toolargetool}" // 需要使用调试时才启用
debugImplementation "com.github.nichbar:WhatTheStack:${whatTheStack}"
debugImplementation "io.github.didi.dokit:dokitx:${dokit}"
// debugImplementation "io.github.didi.dokit:dokitx:${dokit}"
implementation "androidx.multidex:multidex:${multiDex}"
implementation "androidx.fragment:fragment-ktx:${fragment}"
@ -257,6 +277,7 @@ dependencies {
implementation "com.llew.huawei:verifier:${verifier}"
teaImplementation "com.bytedance.applog:RangersAppLog-Lite-cn:${bytedanceApplog}"
teaImplementation "com.bytedance.applog:RangersAppLog-All-convert:${bytedanceApplog}"
implementation "net.lingala.zip4j:zip4j:${zip4j}"
@ -289,12 +310,17 @@ dependencies {
// implementation(project(':module_setting_compose')) {
// exclude group: 'androidx.swiperefreshlayout'
// }
implementation(project(':module_core_feature')){
implementation(project(':module_core_feature')) {
exclude group: 'androidx.swiperefreshlayout'
}
implementation(project(':module_feedback')) {
exclude group: 'androidx.swiperefreshlayout'
}
implementation(project(':module_sensors_data')) {
exclude group: 'androidx.swiperefreshlayout'
}
// implementation(project(':module_vpn'))
implementation(project(':module_pkg'))
// 默认不接入光能模块,提高编译速度
// debugImplementation(project(':module_energy')) {
// exclude group: 'androidx.swiperefreshlayout'

View File

@ -69,4 +69,14 @@
-keep class com.lzf.easyfloat.* {*;}
### dokit
-keep class com.didichuxing.** {*;}
-keep class com.didichuxing.** {*;}
### 广点通SDK
-dontwarn com.qq.gdt.action.**
-keep class com.qq.gdt.action.** {*;}
-keep public class com.tencent.turingfd.sdk.**
-keepclasseswithmembers class * {
native <methods>;
}

View File

@ -0,0 +1,37 @@
package com.gh.gamecenter
import android.app.Application
import com.lightgame.utils.Utils
import com.qq.gdt.action.ActionParam
import com.qq.gdt.action.ActionType
import com.qq.gdt.action.GDTAction
import org.json.JSONObject
object GdtHelper {
private const val USER_ACTION_SET_ID = "1201041887"
private const val APP_SECRET_ID = "c29cc5c48cf540c43b4b97363bb09216"
private const val KS_USER_ACTION_SET_ID = "1201032128"
private const val KS_APP_SECRET_ID = "9bdbbb81d4e0bd333a2a581f9ee36986"
@JvmStatic
fun init(application: Application, channel: String) {
if (channel == "KS_GDT_GHZS_MC01") {
GDTAction.init(application, KS_USER_ACTION_SET_ID, KS_APP_SECRET_ID, channel)
} else {
GDTAction.init(application, USER_ACTION_SET_ID, APP_SECRET_ID, channel)
}
Utils.log("init GdtHelper")
}
@JvmStatic
fun logAction(type: String) {
when (type) {
"EVENT_ACTIVE" -> GDTAction.logAction(ActionType.START_APP)
"active_register" -> GDTAction.logAction(ActionType.REGISTER)
"EVENT_NEXTDAY_STAY" -> GDTAction.logAction(ActionType.START_APP, JSONObject().apply {
put(ActionParam.Key.LENGTH_OF_STAY, 1)
})
}
}
}

View File

@ -0,0 +1,48 @@
package com.gh.gamecenter.provider
import android.app.Activity
import android.app.Application
import android.text.TextUtils
import com.gh.gamecenter.GdtHelper
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
class FlavorProviderImp : IFlavorProvider {
override fun init(application: Application, activity: Activity) {
GdtHelper.init(application, getChannelStr(application))
if (HaloApp.getInstance().isBrandNewInstall) {
logEvent("EVENT_ACTIVE")
SPUtils.setLong("TIME_OF_BRAND_NEW_INSTALL", System.currentTimeMillis() / 1000)
} else {
val shouldSendRetentionLogEvent =
SPUtils.getBoolean("SHOULD_SEND_RETENTION_EVENT", true)
val installTimeNotToday =
!TimeUtils.isToday(SPUtils.getLong("TIME_OF_BRAND_NEW_INSTALL", System.currentTimeMillis() / 1000))
if (shouldSendRetentionLogEvent && installTimeNotToday) {
logEvent("EVENT_NEXTDAY_STAY")
SPUtils.setBoolean("SHOULD_SEND_RETENTION_EVENT", false)
}
}
}
override fun getChannelStr(application: Application): String {
var channel = ChannelReaderUtil.getChannel(application)
if (channel == null || TextUtils.isEmpty(channel.trim())) {
channel = GDT_DEFAULT_CHANNEL
}
return channel
}
override fun logEvent(content: String) {
GdtHelper.logAction(content)
}
companion object {
private const val GDT_DEFAULT_CHANNEL = "GDT_GHZS_01"
}
}

Binary file not shown.

View File

@ -119,6 +119,8 @@
android:name="io.sentry.breadcrumbs.system-events"
android:value="false" />
<service android:name = "com.gh.ndownload.NDownloadService" />
<activity
android:name="com.gh.gamecenter.SplashScreenActivity"
android:configChanges="keyboardHidden|orientation|screenSize"

View File

@ -17,6 +17,7 @@ import com.gh.gamecenter.core.runOnUiThread
import com.gh.gamecenter.core.utils.MD5Utils
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.common.entity.ErrorEntity
import com.gh.gamecenter.entity.ForumDetailEntity
import com.gh.gamecenter.entity.LocalVideoEntity
import com.gh.gamecenter.entity.QuoteCountEntity
import com.gh.gamecenter.qa.BbsType
@ -38,6 +39,7 @@ import kotlin.collections.set
// TODO: 移动到module_bbs模块
abstract class BaseRichEditorViewModel(application: Application) : AndroidViewModel(application) {
val mApi: ApiService = RetrofitManager.getInstance().api
val mNewApi: ApiService = RetrofitManager.getInstance().newApi
val processDialog = MediatorLiveData<WaitingDialogFragment.WaitingDialogData>()
val chooseImagesUpload = MutableLiveData<LinkedHashMap<String, String>>()
val chooseImagesUploadSuccess = MutableLiveData<LinkedHashMap<String, String>>()
@ -55,6 +57,7 @@ abstract class BaseRichEditorViewModel(application: Application) : AndroidViewMo
var id = ""//视频标记
var videoId = ""//更改封面视频id
val quoteCountEntity = QuoteCountEntity()//数据上报用
val sectionListLiveData = MutableLiveData<List<ForumDetailEntity.Section>>()
fun setUploadVideoListener(uploadVideoListener: UploadVideoListener) {
this.mUploadVideoListener = uploadVideoListener
@ -408,6 +411,18 @@ abstract class BaseRichEditorViewModel(application: Application) : AndroidViewMo
return true
}
fun getForumSections(bbsId: String) {
mNewApi.getForumSections(bbsId)
.compose(observableToMain())
.subscribe(object : Response<List<ForumDetailEntity.Section>>() {
override fun onResponse(response: List<ForumDetailEntity.Section>?) {
response?.run {
sectionListLiveData.postValue(this)
}
}
})
}
private fun getVideoType(): String {
return when (type) {
BbsType.GAME_BBS.value -> {

View File

@ -8,6 +8,7 @@ import com.gh.common.util.FloatingBackViewManager
import com.gh.download.DownloadManager
import com.gh.gamecenter.SingletonWebActivity
import com.gh.gamecenter.SplashScreenActivity
import com.gh.gamecenter.common.base.GlobalActivityManager
import com.gh.gamecenter.common.utils.PackageFlavorHelper
import com.gh.vspace.VHelper
import com.halo.assistant.HaloApp

View File

@ -1,14 +0,0 @@
package com.gh.base
import android.app.Activity
import java.lang.ref.WeakReference
object GlobalActivityManager {
private var mCurrentActivityWeakRef: WeakReference<Activity>? = null
var currentActivity: Activity?
get() = mCurrentActivityWeakRef?.get()
set(activity) {
mCurrentActivityWeakRef = WeakReference<Activity>(activity)
}
}

View File

@ -33,6 +33,8 @@ import com.gh.gamecenter.core.runOnIoThread
import com.gh.gamecenter.core.runOnUiThread
import com.gh.gamecenter.core.utils.*
import com.gh.gamecenter.energy.EnergyBridge
import com.gh.gamecenter.entity.SensorsEvent
import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.gh.gamecenter.eventbus.EBPackage
import com.gh.gamecenter.feature.entity.Badge
import com.gh.gamecenter.feature.entity.GameEntity
@ -50,6 +52,9 @@ import com.lightgame.download.DataWatcher
import com.lightgame.download.DownloadEntity
import com.lightgame.download.DownloadStatus.*
import com.lightgame.utils.Utils
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import org.json.JSONObject
import java.io.BufferedOutputStream
import java.io.File
@ -59,12 +64,13 @@ import java.util.*
class DefaultJsApi(var context: Context, val entrance: String = "", private var mFragment: Fragment? = null) {
private var mLoginHandler: CompletionHandler<Any>? = null
private var mDownloadWatcher: DataWatcher? = null
private var mDownloadUrlSet: HashSet<String>? = null
private var mDownloadHandler: CompletionHandler<Any>? = null
private var mDownloadWatcher: DataWatcher? = null // 下载观察者
private var mDownloadUrlSet: HashSet<String>? = null // 下载的 url 集合
private var mDownloadHandler: CompletionHandler<Any>? = null // 下载信息回调
init {
if (mFragment != null) {
EventBus.getDefault().register(this)
autoUnregisterDownloadObserverIfNeeded(mFragment)
}
}
@ -84,6 +90,19 @@ class DefaultJsApi(var context: Context, val entrance: String = "", private var
// do nothing, mta is deprecated
}
@JavascriptInterface
fun logSensorsEvent(event: Any) {
val sensorsEvent = event.toString().toObject() ?: SensorsEvent()
val trackEvent = JSONObject()
tryCatchInRelease {
sensorsEvent.kv.split(",").forEach {
val kv = it.split(":")
trackEvent.put(kv[0], kv[1])
}
}
SensorsBridge.trackEvent(sensorsEvent.name, trackEvent)
}
@JavascriptInterface
fun getUserInfo(msg: Any): String {
return UserManager.getInstance().userInfoEntity?.toJson() ?: ""
@ -187,7 +206,7 @@ class DefaultJsApi(var context: Context, val entrance: String = "", private var
runOnUiThread {
// 若畅玩列表中安装了,优先启动畅玩游戏
if (VHelper.isInstalled(packageName)) {
if (!VHelper.showDialogIfVSpaceIsNeeded(context)) {
if (!VHelper.showDialogIfVSpaceIsNeeded(context, "", "")) {
VHelper.launch(context, packageName)
}
} else {
@ -596,6 +615,8 @@ class DefaultJsApi(var context: Context, val entrance: String = "", private var
if (mDownloadWatcher != null) {
DownloadManager.getInstance().removeObserver(mDownloadWatcher)
}
EventBus.getDefault().unregister(this@DefaultJsApi)
}
}
@ -618,6 +639,14 @@ class DefaultJsApi(var context: Context, val entrance: String = "", private var
)
}
@Subscribe(threadMode = ThreadMode.MAIN)
fun onEventMainThread(status: EBDownloadStatus) {
// 将下载任务删除事件回调给网页
if (mDownloadHandler != null && "delete" == status.status) {
mDownloadHandler?.setProgressData(SimpleDownloadEntity(status.url, 0F, "UNKNOWN").toJson())
}
}
@Keep
internal class ImageEvent(var imageList: ArrayList<String> = arrayListOf(), var position: Int = 0)

View File

@ -18,9 +18,9 @@ import kotlin.concurrent.fixedRateTimer
object FixedRateJobHelper {
private const val CHECKER_PERIOD: Long = 15 * 1000L
private const val TIME_PERIOD: Long = 600 * 1000L
private const val LOGHUB_PERIOD: Long = 120 * 1000L
private const val EXPOSURE_PERIOD: Long = 300 * 1000L
private const val TIME_PERIOD: Long = 10 * 60 * 1000L
private const val LOGHUB_PERIOD: Long = 2 * 60 * 1000L
private const val EXPOSURE_PERIOD: Long = 5 * 60 * 1000L
private const val REGION_SETTING_PERIOD: Long = 30 * 1000L
private const val VIDEO_RECORD_PERIOD: Long = 60 * 1000L
@ -35,9 +35,11 @@ object FixedRateJobHelper {
@JvmStatic
fun begin() {
doOnMainProcessOnly {
// 时间检查每15秒检查一次
fixedRateTimer("Global-Fixed-Rate-Timer", initialDelay = 100, period = CHECKER_PERIOD) {
val elapsedTime = mExecuteCount * CHECKER_PERIOD
// 时间校对10分钟一次
if ((mExecuteCount * CHECKER_PERIOD) % TIME_PERIOD == 0L) {
if (elapsedTime % TIME_PERIOD == 0L) {
RetrofitManager.getInstance().api.time
.subscribeOn(Schedulers.io())
.subscribe(object : Response<TimeEntity>() {
@ -51,14 +53,14 @@ object FixedRateJobHelper {
}
// 提交曝光数据
if ((mExecuteCount * CHECKER_PERIOD) % EXPOSURE_PERIOD == 0L) {
if (elapsedTime % EXPOSURE_PERIOD == 0L) {
runOnUiThread {
ExposureManager.commitSavedExposureEvents(true)
}
}
// 分片检测下载进度
if ((mExecuteCount * CHECKER_PERIOD) % DOWNLOAD_HEARTBEAT_SHEET_PERIOD == 0L) {
if (elapsedTime % DOWNLOAD_HEARTBEAT_SHEET_PERIOD == 0L) {
tryCatchInRelease {
val upload = (mExecuteCount * CHECKER_PERIOD) % DOWNLOAD_HEARTBEAT_PERIOD == 0L
DownloadDataHelper.uploadDownloadHeartbeat(upload)
@ -66,30 +68,29 @@ object FixedRateJobHelper {
}
// 提交普通 loghub 数据
if ((mExecuteCount * CHECKER_PERIOD) % LOGHUB_PERIOD == 0L) {
if (elapsedTime % LOGHUB_PERIOD == 0L) {
runOnUiThread {
LoghubUtils.commitSavedLoghubEvents(true)
}
}
// 更新游戏屏蔽信息
if ((mExecuteCount * CHECKER_PERIOD) % REGION_SETTING_PERIOD == 0L) {
if (elapsedTime % REGION_SETTING_PERIOD == 0L) {
if (HaloApp.getInstance().isRunningForeground) {
RegionSettingHelper.getRegionSetting()
}
}
// 提交视频浏览记录数据
if ((mExecuteCount * CHECKER_PERIOD) % VIDEO_RECORD_PERIOD == 0L) {
if (elapsedTime % VIDEO_RECORD_PERIOD == 0L) {
VideoRecordUtils.commitVideoRecord()
}
// 获取启动广告
if ((mExecuteCount * CHECKER_PERIOD) % STARTUP_AD == 0L) {
// 获取启动广告 (第一次不需要获取)
if (elapsedTime % STARTUP_AD == 0L && mExecuteCount != 0) {
AdHelper.getSettingAdCache()
}
// ExposureUtils.logADownloadCompleteExposureEvent(GameEntity(id = mExecuteCount.toString(), name = "测试曝光上传"), platform = "", trace = null, downloadType = ExposureUtils.DownloadType.DOWNLOAD)
mExecuteCount++
}
}

View File

@ -21,6 +21,7 @@ import com.gh.gamecenter.common.utils.DarkModeUtils;
import com.gh.gamecenter.common.utils.EnvHelper;
import com.gh.gamecenter.core.utils.GsonUtils;
import com.gh.gamecenter.core.utils.SPUtils;
import com.gh.gamecenter.core.utils.UrlFilterUtils;
import com.gh.gamecenter.entity.GameGuidePopupEntity;
import com.gh.gamecenter.entity.NewApiSettingsEntity;
import com.gh.gamecenter.entity.NewSettingsEntity;
@ -76,8 +77,6 @@ public class Config {
public static final String FIX_DOWNLOAD_KEY = "isFixDownload";
public static final String FIX_PLUGIN_KEY = "isFixPlugin";
public static final String FIX_ARTICLE_KEY = "isFixArticle";
public static final String FIX_COMMUNITY_KEY = "isFixCommunity";
public static final int VIDEO_PAGE_SIZE = 21; // 视频列表大多都是一行3个
@ -134,6 +133,18 @@ public class Config {
return !"off".equals(getSettings().getGameSmooth());
}
/**
* VPN 开关选项是否开启
*/
public static boolean isVpnOptionEnabled() {
if (mNewApiSettingsEntity == null
|| mNewApiSettingsEntity.getInstall() == null
|| mNewApiSettingsEntity.getInstall().getVpnRequired() == null) {
return false;
}
return mNewApiSettingsEntity.getInstall().getVpnRequired().getShouldShowVpnOption();
}
public static boolean isShowPlugin(String gameId) {
SharedPreferences preferences = getPreferences();
@ -207,7 +218,7 @@ public class Config {
PackageHelper.initList();
// 初始化畅玩相关的东西
VHelper.init(HaloApp.getInstance(), false);
VHelper.init(HaloApp.getInstance());
}
@Nullable
@ -343,6 +354,10 @@ public class Config {
@SuppressLint("CheckResult")
public static void getGhzsSettings() {
String channel = HaloApp.getInstance().getChannel();
// 把请求提前,避免请求过多阻塞,首页显示广告时老是用到上一次的缓存
getNewSettings(channel);
RetrofitManager.getInstance()
.getApi().getSettings(PackageUtils.getGhVersionName(), channel)
.subscribeOn(Schedulers.io())
@ -379,39 +394,16 @@ public class Config {
}
});
if (mVSetting == null) {
RetrofitManager.getInstance()
.getVApi().getSettings(BuildConfig.VERSION_NAME)
.subscribeOn(Schedulers.io())
.subscribe(new BiResponse<VSetting>() {
@Override
public void onSuccess(VSetting data) {
mVSetting = data;
SPUtils.setString(Constants.SP_V_SETTINGS, GsonUtils.toJson(data));
}
});
}
if (mNewApiSettingsEntity == null) {
RetrofitManager.getInstance()
.getNewApi().getNewSettings(PackageUtils.getGhVersionName(), channel)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new BiResponse<NewApiSettingsEntity>() {
@Override
public void onSuccess(NewApiSettingsEntity data) {
mNewApiSettingsEntity = data;
mNightModeSetting = data.getNightMode();
mNewSimulatorEntity = data.getSimulator();
if (HaloApp.getInstance().isNewForThisVersion && mNightModeSetting != null && mNightModeSetting.getInstall()) {
DarkModeUtils.INSTANCE.updateFollowSystemDarkModeToSp(true);
DarkModeUtils.INSTANCE.initDarkMode();
}
AdHelper.prefetchStartUpAd(mNewApiSettingsEntity);
SPUtils.setString(Constants.SP_NEW_API_SETTINGS, GsonUtils.toJson(data));
}
});
}
RetrofitManager.getInstance()
.getVApi().getSettings(BuildConfig.VERSION_NAME)
.subscribeOn(Schedulers.io())
.subscribe(new BiResponse<VSetting>() {
@Override
public void onSuccess(VSetting data) {
mVSetting = data;
SPUtils.setString(Constants.SP_V_SETTINGS, GsonUtils.toJson(data));
}
});
RetrofitManager.getInstance()
.getApi().getGameGuidePopup(Build.MANUFACTURER, Build.VERSION.RELEASE, Build.MODEL, channel, BuildConfig.VERSION_NAME)
@ -444,4 +436,34 @@ public class Config {
});
}
}
@SuppressLint("CheckResult")
private static void getNewSettings(String channel) {
if (mNewApiSettingsEntity == null) {
String filterString = UrlFilterUtils.getFilterQuery(
"manufacturer", Build.MANUFACTURER,
"model", Build.MODEL,
"android_sdk_version", String.valueOf(Build.VERSION.SDK_INT));
RetrofitManager.getInstance()
.getNewApi().getNewSettings(PackageUtils.getGhVersionName(), channel, filterString)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new BiResponse<NewApiSettingsEntity>() {
@Override
public void onSuccess(NewApiSettingsEntity data) {
mNewApiSettingsEntity = data;
mNightModeSetting = data.getNightMode();
mNewSimulatorEntity = data.getSimulator();
if (HaloApp.getInstance().isNewForThisVersion && mNightModeSetting != null && mNightModeSetting.getInstall()) {
DarkModeUtils.INSTANCE.updateFollowSystemDarkModeToSp(true);
DarkModeUtils.INSTANCE.initDarkMode();
}
AdHelper.prefetchStartUpAd(mNewApiSettingsEntity);
SPUtils.setString(Constants.SP_NEW_API_SETTINGS, GsonUtils.toJson(data));
}
});
}
}
}

View File

@ -31,7 +31,6 @@ import com.gh.common.chain.PackageCheckHandler;
import com.gh.common.chain.ValidateVSpaceHandler;
import com.gh.common.chain.VersionNumberHandler;
import com.gh.common.constant.Config;
import com.gh.gamecenter.feature.exposure.ExposureEvent;
import com.gh.common.filter.RegionSetting;
import com.gh.common.filter.RegionSettingHelper;
import com.gh.common.history.HistoryHelper;
@ -46,11 +45,7 @@ import com.gh.common.util.LogUtils;
import com.gh.common.util.NewsUtils;
import com.gh.common.util.PackageInstaller;
import com.gh.common.util.PackageUtils;
import com.gh.gamecenter.feature.utils.PlatformUtils;
import com.gh.common.util.ReservationHelper;
import com.gh.gamecenter.feature.view.DownloadButton;
import com.gh.gamecenter.feature.view.GameIconView;
import com.gh.gamecenter.common.view.NoEllipsizeSpaceTextView;
import com.gh.download.DownloadManager;
import com.gh.download.dialog.DownloadDialog;
import com.gh.gamecenter.DownloadManagerActivity;
@ -58,25 +53,29 @@ import com.gh.gamecenter.R;
import com.gh.gamecenter.WebActivity;
import com.gh.gamecenter.common.baselist.LoadStatus;
import com.gh.gamecenter.common.callback.OnViewClickListener;
import com.gh.gamecenter.common.entity.LinkEntity;
import com.gh.gamecenter.common.eventbus.EBReuse;
import com.gh.gamecenter.common.utils.DarkModeUtils;
import com.gh.gamecenter.common.utils.ExtensionsKt;
import com.gh.gamecenter.common.utils.ImageUtils;
import com.gh.gamecenter.common.utils.DarkModeUtils;
import com.gh.gamecenter.common.view.DrawableView;
import com.gh.gamecenter.core.utils.DisplayUtils;
import com.gh.gamecenter.core.utils.MtaHelper;
import com.gh.gamecenter.core.utils.NumberUtils;
import com.gh.gamecenter.databinding.KaifuDetailItemRowBinding;
import com.gh.gamecenter.feature.entity.ApkEntity;
import com.gh.gamecenter.feature.entity.CommunityVideoEntity;
import com.gh.gamecenter.feature.entity.GameEntity;
import com.gh.gamecenter.common.entity.LinkEntity;
import com.gh.gamecenter.feature.entity.PluginLocation;
import com.gh.gamecenter.feature.entity.ServerCalendarEntity;
import com.gh.gamecenter.feature.entity.TagStyleEntity;
import com.gh.gamecenter.feature.entity.TestEntity;
import com.gh.gamecenter.common.eventbus.EBReuse;
import com.gh.gamecenter.feature.exposure.ExposureEvent;
import com.gh.gamecenter.feature.utils.PlatformUtils;
import com.gh.gamecenter.feature.view.DownloadButton;
import com.gh.gamecenter.feature.view.GameIconView;
import com.gh.gamecenter.gamedetail.dialog.GamePermissionDialogFragment;
import com.gh.gamecenter.manager.PackagesManager;
import com.gh.gamecenter.feature.entity.CommunityVideoEntity;
import com.gh.vspace.VDownloadManagerActivity;
import com.gh.vspace.VHelper;
import com.lightgame.download.DownloadEntity;
@ -489,7 +488,7 @@ public class BindingAdapters {
case RESERVABLE:
GamePermissionDialogFragment.show((AppCompatActivity) v.getContext(), gameEntity, gameEntity.getInfo(), () -> {
CheckLoginUtils.checkLogin(progressBar.getContext(), "", () -> {
ReservationHelper.reserve(v.getContext(), gameEntity.getId(), () -> {
ReservationHelper.reserve(v.getContext(), gameEntity.getId(), gameEntity.getName(), () -> {
LogUtils.logReservation(gameEntity, traceEvent);
updateReservation(progressBar, gameEntity);
});
@ -594,6 +593,7 @@ public class BindingAdapters {
case pause:
case timeout:
case neterror:
case diskisfull:
case waiting:
progressBar.setText(R.string.downloading);
if (downloadEntity.isPluggable() && PackagesManager.INSTANCE.isInstalled(downloadEntity.getPackageName())) {
@ -785,7 +785,7 @@ public class BindingAdapters {
}
}
public static void setGameName(NoEllipsizeSpaceTextView view, GameEntity game, boolean isShowPlatform, @Nullable Boolean isShowSuffix) {
public static void setGameName(TextView view, GameEntity game, boolean isShowPlatform, @Nullable Boolean isShowSuffix) {
if (isShowSuffix == null) isShowSuffix = true; // 默认显示
String gameName;
if (isShowPlatform && game.getApk().size() > 0) {

View File

@ -22,6 +22,7 @@ import com.gh.gamecenter.R
import com.gh.gamecenter.ShellActivity
import com.gh.gamecenter.common.callback.ConfirmListener
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.utils.SensorsBridge
import com.gh.gamecenter.core.utils.GsonUtils
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.feature.entity.AuthDialogEntity
@ -35,7 +36,7 @@ import com.lightgame.utils.AppManager
class CertificationDialog(
context: Context,
private val authDialogEntity: AuthDialogEntity,
val gameId: String,
val gameEntity: GameEntity,
val listener: ConfirmListener
) :
Dialog(context, R.style.GhAlertDialog) {
@ -69,9 +70,11 @@ class CertificationDialog(
actionRightTv.text = "去实名认证"
noRemindAgainCb.visibility = View.GONE
actionLeftTv.setOnClickListener {
SensorsBridge.trackEvent("VerificationPopupClick", "button_name", actionLeftTv.text.toString())
dismiss()
}
actionRightTv.setOnClickListener {
SensorsBridge.trackEvent("VerificationPopupClick", "button_name", actionRightTv.text.toString())
if (UserManager.getInstance().isLoggedIn) {
gotoAuthPage()
} else {
@ -84,6 +87,7 @@ class CertificationDialog(
actionRightTv.text = "继续下载"
noRemindAgainCb.visibility = View.GONE
actionLeftTv.setOnClickListener {
SensorsBridge.trackEvent("VerificationPopupClick", "button_name", actionLeftTv.text.toString())
if (UserManager.getInstance().isLoggedIn) {
gotoAuthPage()
} else {
@ -91,6 +95,7 @@ class CertificationDialog(
}
}
actionRightTv.setOnClickListener {
SensorsBridge.trackEvent("VerificationPopupClick", "button_name", actionRightTv.text.toString())
listener.onConfirm()
dismiss()
}
@ -100,8 +105,9 @@ class CertificationDialog(
actionRightTv.text = "继续下载"
noRemindAgainCb.visibility = View.VISIBLE
actionLeftTv.setOnClickListener {
SensorsBridge.trackEvent("VerificationPopupClick", "button_name", actionLeftTv.text.toString())
if (noRemindAgainCb.isChecked) {
SPUtils.setBoolean(gameId, true)
SPUtils.setBoolean(gameEntity.id, true)
}
if (UserManager.getInstance().isLoggedIn) {
gotoAuthPage()
@ -110,14 +116,25 @@ class CertificationDialog(
}
}
actionRightTv.setOnClickListener {
SensorsBridge.trackEvent("VerificationPopupClick", "button_name", actionRightTv.text.toString())
if (noRemindAgainCb.isChecked) {
SPUtils.getBoolean(gameId, true)
SPUtils.getBoolean(gameEntity.id, true)
}
listener.onConfirm()
dismiss()
}
}
}
SensorsBridge.trackEvent(
"VerificationDialogShow",
"game_id",
gameEntity.id,
"game_name",
gameEntity.name ?: "",
"game_type",
gameEntity.categoryChinese
)
}
//跳转登录页面
@ -145,7 +162,7 @@ class CertificationDialog(
context,
ShellActivity.Type.REAL_NAME_INFO,
).apply {
putExtra(EntranceConsts.KEY_GAME_ID, gameId)
putExtra(EntranceConsts.KEY_GAME_ID, gameEntity.id)
}, object : Callback {
override fun onActivityResult(resultCode: Int, data: Intent?) {
if (resultCode == Activity.RESULT_OK && data != null) {
@ -194,7 +211,7 @@ class CertificationDialog(
}
val isCloseAuthDialog = SPUtils.getBoolean(game.id, false)
if (authDialog != null && (authDialog.level != AuthDialogLevel.OPTIONAL_HINT.value || !isCloseAuthDialog)) {
val dialog = CertificationDialog(context, authDialog, game.id, listener)
val dialog = CertificationDialog(context, authDialog, game, listener)
dialog.show()
} else {
listener.onConfirm()

View File

@ -88,7 +88,6 @@ object ExposureManager {
eliminateMultipleBrackets(event.eTrace?.toJson() ?: "")
} else ""
)
logTime = event.time.toLong()
}
}

View File

@ -18,6 +18,9 @@ import io.reactivex.schedulers.Schedulers
object RegionSettingHelper {
// 是否是初始化调用
private var mIsInit = true
private var mChannelControl: RegionSetting.ChannelControl? = null
private var mFilterGameIdSet: HashSet<String>? = hashSetOf()
private var mDisplayMirrorIfoGameIdSet: HashSet<String>? = hashSetOf()
@ -28,6 +31,7 @@ object RegionSettingHelper {
private const val SP_SETTING = "region_setting"
const val SP_SETTING_FAILURE = "region_setting_failure"
@JvmStatic
fun shouldThisGameDisplayMirrorInfo(gameId: String): Boolean {
return mDisplayMirrorIfoGameIdSet?.contains(gameId) ?: false
}
@ -95,6 +99,15 @@ object RegionSettingHelper {
@JvmStatic
fun getRegionSetting() {
debounceActionWithInterval(R.string.app_name, 5000) {
// 初始启动时先使用历史数据
if (mIsInit) {
SPUtils.getString(SP_SETTING).toObject<RegionSetting>()?.let {
updateSettingsInMemory(it)
}
mIsInit = false
}
// 使用默认的 Schdulers.io() 可能会触发 OOM
RetrofitManager.getInstance()
.api

View File

@ -2,17 +2,17 @@ package com.gh.common.provider
import android.content.Context
import android.widget.LinearLayout
import android.widget.TextView
import com.alibaba.android.arouter.facade.annotation.Route
import com.gh.common.databind.BindingAdapters
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.common.view.NoEllipsizeSpaceTextView
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.provider.IBindingAdaptersProvider
@Route(path = RouteConsts.provider.bindingAdapters, name = "BindingAdapters暴露服务")
class BindingAdaptersProviderImpl : IBindingAdaptersProvider {
override fun setGameName(
view: NoEllipsizeSpaceTextView,
view: TextView,
game: GameEntity,
isShowPlatform: Boolean,
isShowSuffix: Boolean

View File

@ -5,6 +5,7 @@ import com.alibaba.android.arouter.facade.annotation.Route
import com.gh.common.util.ErrorHelper
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.core.provider.IErrorHelperProvider
import com.gh.gamecenter.login.user.LoginTag
import retrofit2.HttpException
@Route(path = RouteConsts.provider.errorHelper, name = "ErrorHelper暴露服务")
@ -18,8 +19,13 @@ class ErrorHelperProviderImpl : IErrorHelperProvider {
ErrorHelper.handleError(context, errorString, showHighPriorityHint)
}
override fun handleLoginError(context: Context, httpException: HttpException?) {
ErrorHelper.handleLoginError(context, httpException)
override fun handleLoginError(
context: Context,
httpException: HttpException?,
loginTagChinese: String,
isCertificate: Boolean
) {
ErrorHelper.handleLoginError(context, httpException, loginTagChinese, isCertificate)
}
override fun init(context: Context?) {

View File

@ -22,8 +22,12 @@ import com.gh.gamecenter.core.utils.*
import com.gh.gamecenter.feature.entity.ApkEntity
import com.gh.gamecenter.feature.entity.SimulatorEntity
import com.gh.gamecenter.entity.TrackableEntity
import com.gh.ndownload.NDataChanger
import com.halo.assistant.HaloApp
import com.lightgame.download.*
import com.lightgame.download.DataWatcher
import com.lightgame.download.DownloadEntity
import com.lightgame.download.DownloadStatus
import com.lightgame.download.FileUtils
import com.lightgame.utils.Utils
import java.lang.ref.WeakReference
import java.text.DecimalFormat
@ -95,6 +99,9 @@ class SimulatorDownloadManager private constructor() {
downloadDialog?.dismiss()
}
}
DownloadStatus.diskisfull == downloadEntity.status -> {
ToastUtils.showToast("存储空间已满,下载任务已暂停")
}
DownloadStatus.neterror == downloadEntity.status -> {
ToastUtils.showToast("网络不稳定,下载任务已暂停")
}
@ -290,13 +297,16 @@ class SimulatorDownloadManager private constructor() {
HaloApp.put(simulator.name, simulator)
if (entity != null) {
when (entity.status) {
DownloadStatus.pause, DownloadStatus.subscribe,
DownloadStatus.neterror, DownloadStatus.timeout -> {
DownloadStatus.pause,
DownloadStatus.subscribe,
DownloadStatus.neterror,
DownloadStatus.timeout,
DownloadStatus.diskisfull -> {
DownloadManager.getInstance().addObserver(dataWatcher)
uiExecutor.executeWithDelay(Runnable { DownloadManager.getInstance().resume(entity, true) }, 200)
downloadDialog?.show()
}
DownloadStatus.done -> DataChanger.notifyDataChanged(entity)
DownloadStatus.done -> NDataChanger.notifyDataChanged(entity)
else -> createDownload(apkEntity, simulator)
}

View File

@ -10,15 +10,13 @@ import com.gh.download.simple.AutoUnregisteredSimpleDownloadListener
import com.gh.download.simple.DownloadListener
import com.gh.gamecenter.R
import com.gh.gamecenter.common.eventbus.EBReuse
import com.gh.gamecenter.common.utils.DialogHelper
import com.gh.gamecenter.common.utils.dip2px
import com.gh.gamecenter.common.utils.roundTo
import com.gh.gamecenter.common.utils.toResString
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.runOnUiThread
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.databinding.DialogArchiveLoadingBinding
import com.gh.gamecenter.entity.ArchiveEntity
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.retrofit.RetrofitManager
import com.gh.vspace.VArchiveHelper
import com.gh.vspace.VHelper
@ -40,6 +38,7 @@ object ArchiveDownloadButtonHelper {
packageName: String,
archiveEntity: ArchiveEntity,
downloadBtn: TextView,
gameEntity: GameEntity?,
downloadCompletedListener: (() -> Unit)? = null
) {
downloadBtn.text = if (VArchiveHelper.isArchiveDownloaded(archiveEntity.md5)) {
@ -50,7 +49,7 @@ object ArchiveDownloadButtonHelper {
downloadBtn.setOnClickListener {
when {
// 检查是否已安装畅玩助手
!VHelper.isVSpaceInstalled(context) -> showVspaceTipDialog(context)
!VHelper.isVSpaceInstalled(context) -> showVspaceTipDialog(context, gameEntity)
// 检查是否已安装游戏
!VHelper.isInstalled(packageName) -> {
// 检查游戏是否在安装中
@ -65,7 +64,8 @@ object ArchiveDownloadButtonHelper {
context,
entrance,
packageName,
archiveEntity
archiveEntity,
gameEntity
)
// 检查完毕下载存档
else -> downloadArchive(
@ -75,13 +75,14 @@ object ArchiveDownloadButtonHelper {
packageName,
archiveEntity,
downloadBtn,
gameEntity,
downloadCompletedListener
)
}
}
}
private fun showVspaceTipDialog(context: Context) {
private fun showVspaceTipDialog(context: Context, gameEntity: GameEntity?) {
NewFlatLogUtils.logCloudArchiveVSpaceDownloadDialogShow()
DialogHelper.showDialog(
context,
@ -91,7 +92,7 @@ object ArchiveDownloadButtonHelper {
R.string.cancel.toResString(),
{
NewFlatLogUtils.logCloudArchiveVSpaceDownloadDialogClick(R.string.archive_vspace_dialog_confirm.toResString())
VHelper.showVspaceDialog(context)
VHelper.showVspaceDialog(context, gameEntity)
},
{
NewFlatLogUtils.logCloudArchiveVSpaceDownloadDialogClick(R.string.cancel.toResString())
@ -154,6 +155,7 @@ object ArchiveDownloadButtonHelper {
packageName: String,
archiveEntity: ArchiveEntity,
downloadBtn: TextView,
gameEntity: GameEntity?,
downloadCompletedListener: (() -> Unit)? = null
) {
// 执行下载
@ -187,7 +189,7 @@ object ArchiveDownloadButtonHelper {
DownloadStatus.COMPLETED -> {
dismissArchiveLoadingDialog(archiveLoadingDialog)
downloadBtn.text = R.string.archive_apply.toResString()
showApplyArchiveTipDialog(context, entrance, packageName, archiveEntity)
showApplyArchiveTipDialog(context, entrance, packageName, archiveEntity, gameEntity)
downloadCompletedListener?.invoke()
}
else -> {
@ -203,6 +205,14 @@ object ArchiveDownloadButtonHelper {
})
NewFlatLogUtils.logCloudArchiveDownloadOrApply(archiveEntity.name, entrance)
SensorsBridge.trackEvent(
"CloudSaveDownload",
"cloud_save_name", archiveEntity.name,
"game_id", gameEntity?.id ?: "",
"game_name", gameEntity?.name ?: "",
"source_entrance", entrance
)
}
private fun showArchiveLoadingDialog(
@ -226,7 +236,8 @@ object ArchiveDownloadButtonHelper {
context: Context,
entrance: String,
packageName: String,
archiveEntity: ArchiveEntity
archiveEntity: ArchiveEntity,
gameEntity: GameEntity?
) {
DialogHelper.showDialog(
context,
@ -237,12 +248,31 @@ object ArchiveDownloadButtonHelper {
{
applyArchive(context, entrance, packageName, archiveEntity)
NewFlatLogUtils.logCloudArchiveApplyDialogRelated("cloud_save_overwrite_dialog_click", "使用")
SensorsBridge.trackEvent(
"CloudSaveOverwriteDialogClick",
"game_id", gameEntity?.id ?: "",
"game_name", gameEntity?.name ?: "",
"button_name", "使用"
)
},
{
NewFlatLogUtils.logCloudArchiveApplyDialogRelated("cloud_save_overwrite_dialog_click", "取消")
SensorsBridge.trackEvent(
"CloudSaveOverwriteDialogClick",
"game_id", gameEntity?.id ?: "",
"game_name", gameEntity?.name ?: "",
"button_name", "取消"
)
},
{ NewFlatLogUtils.logCloudArchiveApplyDialogRelated("cloud_save_overwrite_dialog_click", "取消") },
extraConfig = DialogHelper.Config(centerTitle = true)
)
NewFlatLogUtils.logCloudArchiveApplyDialogRelated("cloud_save_overwrite_dialog_show")
SensorsBridge.trackEvent(
"CloudSaveOverwriteDialogShow",
"game_id", gameEntity?.id ?: "",
"game_name", gameEntity?.name ?: ""
)
}
private fun dismissArchiveLoadingDialog(archiveLoadingDialog: Dialog) {

View File

@ -9,12 +9,14 @@ import android.preference.PreferenceManager;
import android.text.TextUtils;
import android.util.Log;
import com.gh.base.GlobalActivityManager;
import com.gh.gamecenter.common.base.GlobalActivityManager;
import com.gh.gamecenter.BuildConfig;
import com.gh.gamecenter.common.base.activity.BaseActivity;
import com.gh.gamecenter.common.constant.Constants;
import com.gh.gamecenter.common.eventbus.EBReuse;
import com.gh.gamecenter.common.exposure.meta.MetaUtil;
import com.gh.gamecenter.common.retrofit.BiResponse;
import com.gh.gamecenter.common.utils.SensorsBridge;
import com.gh.gamecenter.core.AppExecutor;
import com.gh.gamecenter.core.utils.GsonUtils;
import com.gh.gamecenter.core.utils.MtaHelper;
@ -30,6 +32,8 @@ import com.halo.assistant.HaloApp;
import com.lightgame.config.CommonDebug;
import com.lightgame.utils.Utils;
import org.greenrobot.eventbus.EventBus;
import io.reactivex.schedulers.Schedulers;
import io.sentry.Sentry;
import io.sentry.android.core.SentryAndroid;
@ -114,6 +118,13 @@ public class DataUtils {
String originalGid = HaloApp.getInstance().getGid();
HaloApp.getInstance().setGid(gid);
// gid 变更时上报 gid 变更日志
if (!TextUtils.isEmpty(originalGid) && !originalGid.equals(gid)) {
NewFlatLogUtils.logGidChanged(originalGid, gid);
}
SensorsBridge.setGid(gid);
// 避免重复调用
if (!TextUtils.isEmpty(gid) && !gid.equals(originalGid)) {
GameSubstituteRepositoryHelper.updateSubstitutableGames();
@ -170,6 +181,8 @@ public class DataUtils {
values.put(GhContentProvider.KEY_IS_ADULT, false);
}
EventBus.getDefault().post(new EBReuse(Constants.EB_REALNAME_RESULT));
// new GhContentProvider().localInsert( HaloApp.getInstance().getApplication(),values);
try {
// Unknown URL content://com.gh.gamecenter.provider/certification

View File

@ -262,6 +262,7 @@ public class DetailDownloadUtils {
case downloading:
case redirected:
case pause:
case diskisfull:
case overflow:
String downloadingText = "游戏加载中 " + downloadEntity.getPercent() + "%";
String resumeText = "继续加载 " + downloadEntity.getPercent() + "%";
@ -348,6 +349,7 @@ public class DetailDownloadUtils {
case timeout:
case neterror:
case subscribe:
case diskisfull:
case pause:
viewHolder.mDownloadPb.setText("继续加载 " + viewHolder.downloadEntity.getPercent() + "%");
viewHolder.mDownloadPb.setButtonStyle(DownloadButton.ButtonStyle.DOWNLOADING_NORMAL);

View File

@ -56,6 +56,7 @@ 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.common.utils.NetworkUtils;
import com.gh.gamecenter.common.utils.SensorsBridge;
import com.gh.gamecenter.common.view.CustomLinkMovementMethod;
import com.gh.gamecenter.common.view.DrawableView;
import com.gh.gamecenter.common.view.FixLinearLayoutManager;
@ -910,6 +911,8 @@ public class DialogUtils {
public static void showRegulationTestDialog(Context context, @NonNull ConfirmListener confirmListener, @NonNull CancelListener cancelListener) {
context = checkDialogContext(context);
SensorsBridge.trackEvent("EtiquetteTestDialogShow");
final Dialog dialog = new TrackableDialog(
context,
R.style.GhAlertDialog,
@ -935,6 +938,7 @@ public class DialogUtils {
cancelListener.onCancel();
MtaHelper.onEvent("礼仪考试", "礼仪考试弹窗", "跳过");
SensorsBridge.trackEvent("EtiquetteTestDialogClick", "button_name", "跳过");
dialog.dismiss();
});
@ -943,6 +947,7 @@ public class DialogUtils {
Util_System_Keyboard.hideSoftKeyboard((Activity) finalContext1);
MtaHelper.onEvent("礼仪考试", "礼仪考试弹窗", "确定");
SensorsBridge.trackEvent("EtiquetteTestDialogClick", "button_name", "进入考试");
confirmListener.onConfirm();
dialog.dismiss();
});

View File

@ -28,6 +28,7 @@ import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.constant.EntranceConsts.*
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.common.entity.*
import com.gh.gamecenter.common.entity.Display
import com.gh.gamecenter.common.retrofit.Response
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.runOnIoThread
@ -36,6 +37,7 @@ import com.gh.gamecenter.discovery.DiscoveryActivity
import com.gh.gamecenter.download.DownloadFragment.Companion.INDEX_UPDATE
import com.gh.gamecenter.entity.*
import com.gh.gamecenter.eventbus.EBSkip
import com.gh.gamecenter.feature.entity.GameDetailServer
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.entity.MeEntity
import com.gh.gamecenter.feature.exposure.ExposureEvent
@ -186,7 +188,8 @@ object DirectUtils {
"game_list",
"game_list_detail",
"bbs_video",
"explore_column"
"explore_column",
"column_test_v2"
)
fun directToLinkPage(
@ -348,6 +351,13 @@ object DirectUtils {
"bbs_detail" -> directForumDetail(context, linkEntity.link ?: "", entrance)
"bbs_section" -> directForumDetailSection(
context,
linkEntity.community?.id,
linkEntity.link ?: "",
entrance
)
"mobile_bind" -> {
CheckLoginUtils.checkLogin(context, entrance) {
context.startActivity(SettingBridge.getBindPhoneNormalIntent(context, false))
@ -1414,6 +1424,21 @@ object DirectUtils {
jumpActivity(context, bundle)
}
@JvmStatic
fun directForumDetailSection(
context: Context,
bbsId: String? = "",
sectionId: String = "",
entrance: String? = null
) {
val bundle = Bundle()
bundle.putString(KEY_TO, ForumDetailActivity::class.java.name)
bundle.putString(KEY_BBS_ID, bbsId)
bundle.putString(KEY_BBS_SECTION_ID, sectionId)
bundle.putString(KEY_ENTRANCE, entrance)
jumpActivity(context, bundle)
}
/**
* 到首页-首页 tab
*/

View File

@ -7,17 +7,16 @@ 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
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.common.filter.RegionSettingHelper
import com.gh.common.history.HistoryHelper
import com.gh.common.repository.ReservationRepository
import com.gh.common.simulator.NewSimulatorGameManager
import com.gh.common.simulator.SimulatorDownloadManager
import com.gh.common.simulator.SimulatorGameManager
import com.gh.gamecenter.feature.view.DownloadButton
import com.gh.common.xapk.XapkInstaller
import com.gh.common.xapk.XapkInstaller.cancelUnzipTask
import com.gh.common.xapk.XapkUnzipStatus
@ -35,6 +34,8 @@ import com.gh.gamecenter.core.utils.*
import com.gh.gamecenter.energy.EnergyBridge
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.entity.PluginLocation
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.feature.view.DownloadButton
import com.gh.gamecenter.gamedetail.dialog.GamePermissionDialogFragment
import com.gh.gamecenter.manager.PackagesManager
import com.gh.gamecenter.teenagermode.TeenagerModeActivity
@ -309,6 +310,7 @@ object DownloadItemUtils {
DownloadStatus.timeout,
DownloadStatus.neterror,
DownloadStatus.subscribe,
DownloadStatus.diskisfull,
DownloadStatus.overflow -> {
buttonStyle = DownloadButton.ButtonStyle.NORMAL
setText(R.string.resume)
@ -428,6 +430,7 @@ object DownloadItemUtils {
DownloadStatus.pause,
DownloadStatus.timeout,
DownloadStatus.neterror,
DownloadStatus.diskisfull,
DownloadStatus.subscribe,
DownloadStatus.overflow -> {
if (isMultiVersion) {
@ -592,6 +595,7 @@ object DownloadItemUtils {
gamePermissionDialogFragment?.dismissAllowingStateLoss()
if (SPUtils.getBoolean(Constants.SP_TEENAGER_MODE)) {
downloadBtn.setOnClickListener {
logDownloadButtonClick(gameEntity, downloadBtn)
DialogHelper.showDialog(
context,
"提示",
@ -611,6 +615,7 @@ object DownloadItemUtils {
if (gameEntity.isSpecialDownload()) {
val info = RegionSettingHelper.getGameSpecialDownloadInfo(gameEntity.id) ?: return
downloadBtn.setOnClickListener {
logDownloadButtonClick(gameEntity, downloadBtn)
DialogHelper.showDialog(
context,
"提示",
@ -638,16 +643,27 @@ object DownloadItemUtils {
if (gameEntity.isReservable) {
if (!ReservationRepository.thisGameHasBeenReserved(gameEntity.id)) {
downloadBtn.setOnClickListener {
SensorsBridge.trackEvent(
"AppointmentGame",
"game_name",
gameEntity.name ?: "",
"game_id",
gameEntity.id
)
allStateClickCallback?.onCallback()
CheckLoginUtils.checkLogin(context, entrance) {
clickCallback?.onCallback()
ReservationHelper.reserve(context, gameEntity.id, object : EmptyCallback {
override fun onCallback() {
LogUtils.logReservation(gameEntity, traceEvent)
adapter?.notifyItemChanged(position)
refreshCallback?.onCallback()
}
})
ReservationHelper.reserve(
context,
gameEntity.id,
gameEntity.name ?: "",
object : EmptyCallback {
override fun onCallback() {
LogUtils.logReservation(gameEntity, traceEvent)
adapter?.notifyItemChanged(position)
refreshCallback?.onCallback()
}
})
}
}
} else {
@ -689,12 +705,14 @@ object DownloadItemUtils {
val gameH5Download = RegionSettingHelper.getGameH5DownloadByGameId(gameEntity.id)
if (gameH5Download != null) {
downloadBtn.setOnClickListener {
logDownloadButtonClick(gameEntity, downloadBtn)
DialogUtils.showGameH5DownloadDialog(context, gameEntity, gameH5Download)
}
return
}
if (gameEntity.getApk().size == 0 && gameEntity.h5Link != null) {
downloadBtn.setOnClickListener {
logDownloadButtonClick(gameEntity, downloadBtn)
allStateClickCallback?.onCallback()
MtaHelper.onEvent("H5页面", "入口", "列表页_" + gameEntity.name)
val linkEntity = gameEntity.h5Link
@ -713,6 +731,7 @@ object DownloadItemUtils {
}
} else if (gameEntity.getApk().size == 1) {
downloadBtn.setOnClickListener {
logDownloadButtonClick(gameEntity, downloadBtn)
val clickRunnable = EmptyCallback {
allStateClickCallback?.onCallback()
clickCallback?.onCallback()
@ -1039,4 +1058,22 @@ object DownloadItemUtils {
) {
DownloadManager.createDownload(context, gameEntity, "更新", entrance, location, isSubscribe, traceEvent)
}
private fun logDownloadButtonClick(gameEntity: GameEntity, downloadBtn: View) {
val buttonName = if (downloadBtn is DownloadButton) downloadBtn.text else ""
SensorsBridge.trackEvent(
"DownLoadbuttonClick",
"game_id", gameEntity.id,
"game_name", gameEntity.name ?: "",
"game_type", gameEntity.categoryChinese,
"download_status", gameEntity.downloadStatusChinese,
"button_name", buttonName,
"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

@ -98,18 +98,19 @@ object DownloadNotificationHelper {
DownloadStatus.waiting -> builder.setContentText("等待中")
DownloadStatus.subscribe,
DownloadStatus.timeout,
DownloadStatus.diskisfull,
DownloadStatus.neterror -> builder.setContentText("已暂停连接WiFi自动下载")
else -> builder.setContentText("暂停中")
}
builder.setProgress(PROGRESS_MAX, entity.percent.toInt(), false)
}
when {
entity.status == DownloadStatus.done -> {
when (entity.status) {
DownloadStatus.done -> {
builder.setSortKey("A")
builder.setOngoing(true) // 垃圾华为 sortKey 不起效 priority 也不起效,要将下载完成任务的通知置顶只能设置为 ongoing喷了
}
entity.status == DownloadStatus.downloading -> builder.setSortKey("B")
DownloadStatus.downloading -> builder.setSortKey("B")
else -> builder.setSortKey("C")
}

View File

@ -1,5 +1,7 @@
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
@ -16,6 +18,7 @@ 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.energy.EnergyBridge
import com.gh.gamecenter.eventbus.EBDownloadStatus
@ -84,7 +87,9 @@ object DownloadObserver {
)
}, extraConfig = DialogHelper.Config(centerTitle = true, centerContent = true))
return
} else if (DownloadStatus.neterror == downloadEntity.status || DownloadStatus.timeout == downloadEntity.status) {
} else if (DownloadStatus.neterror == downloadEntity.status
|| DownloadStatus.timeout == downloadEntity.status
|| DownloadStatus.diskisfull == downloadEntity.status) {
if (downloadEntity.meta[Constants.MARK_RETRY_DOWNLOAD].isNullOrEmpty()
&& NetworkUtils.isWifiConnected(HaloApp.getInstance().application)
) {
@ -95,7 +100,12 @@ object DownloadObserver {
Utils.log("DownloadObserver", "下载重试->" + downloadEntity.toJson())
}
} else {
Utils.toast(mApplication, "网络不稳定,下载任务已暂停")
if (DownloadStatus.diskisfull == downloadEntity.status) {
ToastUtils.toast("磁盘已满,请清理空间后重试下载")
} else {
ToastUtils.toast("网络不稳定,下载任务已暂停")
}
DataLogUtils.uploadNeterrorLog(mApplication, downloadEntity)
debugOnly {
@ -371,6 +381,27 @@ object DownloadObserver {
type = ExposureUtils.DownloadType.PLUGIN_DOWNLOAD
}
if (downloadEntity.isVGame()) {
SensorsBridge.trackEvent(
"HaloFunGameDownloadDone",
"game_name", downloadEntity.name,
"game_id", downloadEntity.gameId
)
} else if (downloadEntity.gameId != "62bd412bbbf04747cd3de539") {
SensorsBridge.trackEvent(
"DownloadProcessFinish",
"game_id", downloadEntity.gameId,
"game_name", downloadEntity.meta[Constants.GAME_NAME] ?: "",
"game_type", downloadEntity.meta[Constants.GAME_TYPE] ?: "",
"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
)
}
var downloadSpeed = 0L
val elapsedTimeString = downloadEntity.meta[DownloadConfig.KEY_DOWNLOAD_ELAPSED_TIME]
if (elapsedTimeString != null) {
@ -393,7 +424,9 @@ object DownloadObserver {
id = downloadEntity.gameId,
mName = downloadEntity.name.removeSuffix(Constants.GAME_NAME_DECORATOR),
gameVersion = downloadEntity.versionName ?: "",
isPlatformRecommend = isPlatformRecommend
isPlatformRecommend = isPlatformRecommend,
adIconActive = downloadEntity.meta[Constants.AD_ICON_ACTIVE].toBoolean(),
isAdData = downloadEntity.meta[Constants.IS_AD_DATA].toBoolean()
),
downloadEntity.platform,
downloadEntity.exposureTrace,

View File

@ -15,11 +15,10 @@ import com.gh.gamecenter.common.avoidcallback.AvoidOnResultManager
import com.gh.gamecenter.common.avoidcallback.Callback
import com.gh.gamecenter.common.callback.ConfirmListener
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.utils.DialogHelper
import com.gh.gamecenter.common.utils.dip2px
import com.gh.gamecenter.common.utils.toColor
import com.gh.gamecenter.common.utils.toObject
import com.gh.gamecenter.common.entity.ErrorEntity
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.utils.SensorsBridge
import com.gh.gamecenter.login.user.LoginTag
import com.halo.assistant.fragment.user.UserInfoEditFragment
import com.halo.assistant.fragment.user.VerifyPhoneFragment
import com.lightgame.utils.AppManager
@ -403,23 +402,50 @@ object ErrorHelper {
}
@JvmStatic
fun handleLoginError(context: Context, httpException: HttpException?) {
fun handleLoginError(
context: Context,
httpException: HttpException?,
loginTagChinese: String,
isCertificate: Boolean
) {
try {
var errorReason = ""
val errorEntity: ErrorEntity? =
httpException?.response()?.errorBody()?.string()?.toObject()
when {
errorEntity?.code == 403099 -> Utils.toast(context, "当前账号正在注销,禁止登录")
errorEntity?.code == 403099 -> {
errorReason = "当前账号正在注销,禁止登录"
Utils.toast(context, errorReason)
}
// 用户禁止登录
errorEntity?.code == 403401 -> Utils.toast(context, "您的账号存在违规,不允许登录")
errorEntity?.code == 403401 -> {
errorReason = "您的账号存在违规,不允许登录"
Utils.toast(context, errorReason)
}
// 设备禁止登录
errorEntity?.code == 403404 -> Utils.toast(context, "您的设备存在违规,不允许登录")
errorEntity?.code == 403404 -> {
errorReason = "您的设备存在违规,不允许登录"
Utils.toast(context, errorReason)
}
errorEntity?.toast?.isNotEmpty() == true -> Utils.toast(context, errorEntity.toast)
errorEntity?.toast?.isNotEmpty() == true -> {
Utils.toast(context, errorEntity.toast)
errorReason = errorEntity.toast!!
}
else -> Utils.toast(context, R.string.login_failure)
}
if (!isCertificate) SensorsBridge.trackEvent(
"LoginResult",
"login_type",
loginTagChinese,
"login_result",
"失败",
"defeated_reason",
errorReason
)
} catch (e: Exception) {
e.printStackTrace()
Utils.toast(context, R.string.login_failure)

View File

@ -138,7 +138,7 @@ object GameActivityDownloadHelper {
) {
if (!ReservationRepository.thisGameHasBeenReserved(gameEntity.id)) {
CheckLoginUtils.checkLogin(context, entrance) {
ReservationHelper.reserve(context, gameEntity.id, object : EmptyCallback {
ReservationHelper.reserve(context, gameEntity.id, gameEntity.name ?: "", object : EmptyCallback {
override fun onCallback() {
LogUtils.logReservation(gameEntity, traceEvent)
clear()

View File

@ -18,6 +18,7 @@ import com.gh.gamecenter.adapter.LibaoDetailAdapter;
import com.gh.gamecenter.common.utils.DialogHelper;
import com.gh.gamecenter.common.utils.ExtensionsKt;
import com.gh.gamecenter.common.utils.NotificationHelper;
import com.gh.gamecenter.common.utils.SensorsBridge;
import com.gh.gamecenter.core.utils.ToastUtils;
import com.gh.gamecenter.core.utils.UrlFilterUtils;
import com.gh.gamecenter.feature.entity.ApkEntity;
@ -305,7 +306,7 @@ public class LibaoUtils {
public static void initLibaoBtn(final Context context, final TextView libaoBtn, final LibaoEntity libaoEntity,
final boolean isInstallRequired, final LibaoDetailAdapter adapter, boolean shouldUpdateStatus,
final String entrance, final OnLibaoStatusChangeListener listener) {
final String entrance, final String sourceEntrance, final OnLibaoStatusChangeListener listener) {
setLiBaoBtnStatusRound(libaoBtn, libaoEntity, shouldUpdateStatus, context);
String status = libaoEntity.getStatus();
@ -318,6 +319,32 @@ public class LibaoUtils {
}
}
// 类型为复制的,不需要登录也可以直接复制
if ("copy".equals(libaoEntity.getReceiveMethod())) {
if ("finish".equals(libaoEntity.getStatus())) {
libaoBtn.setText(R.string.libao_finish);
libaoBtn.setBackgroundResource(R.drawable.button_border_round_gray);
libaoBtn.setTextColor(context.getResources().getColor(R.color.button_gray));
libaoBtn.setOnClickListener(v -> ToastUtils.toast("兑换码领取已结束"));
} else {
libaoBtn.setText(R.string.libao_copy);
libaoBtn.setTextColor(ExtensionsKt.toColor(R.color.white, context));
libaoBtn.setBackgroundResource(R.drawable.button_normal_round_style);
libaoBtn.setOnClickListener(v -> {
LogUtils.uploadReceiveGift(
"game_gift_code_successful",
libaoEntity.getId(),
libaoEntity.getName(),
"游戏详情",
libaoEntity.getGame().getId(),
libaoEntity.getGame().getName()
);
ExtensionsKt.copyTextAndToast(libaoEntity.getCode(), libaoEntity.getToast());
});
}
return;
}
libaoBtn.setOnClickListener(v -> {
String btnStatus = libaoBtn.getText().toString();
// 领取限制
@ -380,13 +407,29 @@ public class LibaoUtils {
if ("repeatLing".equals(status)) {
ToastUtils.showToast("礼包每天0点刷新明日0点后可再领一个");
} else {
libaoLing(context, libaoBtn, libaoEntity, adapter, isInstallRequired, null, entrance, listener);
libaoLing(context, libaoBtn, libaoEntity, adapter, isInstallRequired, null, entrance, sourceEntrance, listener);
}
SensorsBridge.trackEvent("GameGiftDraw",
"gift_type", "普通礼包",
"game_name", libaoEntity.getGame().getName(),
"game_id", libaoEntity.getGame().getId(),
"gift_id", libaoEntity.getId(),
"gift_name", libaoEntity.getName(),
"source_entrance", sourceEntrance
);
break;
case "再淘":
case "再淘一个":
case "淘号":
libaoTao(context, libaoBtn, libaoEntity, isInstallRequired, adapter, status, entrance, listener);
libaoTao(context, libaoBtn, libaoEntity, isInstallRequired, adapter, status, entrance, sourceEntrance, listener);
SensorsBridge.trackEvent("GameGiftDraw",
"gift_type", "淘号礼包",
"game_name", libaoEntity.getGame().getName(),
"game_id", libaoEntity.getGame().getId(),
"gift_id", libaoEntity.getId(),
"gift_name", libaoEntity.getName(),
"source_entrance", sourceEntrance
);
break;
}
});
@ -394,7 +437,7 @@ public class LibaoUtils {
}
private static void libaoTao(Context context, TextView libaoBtn, LibaoEntity libaoEntity, boolean isInstallRequired, LibaoDetailAdapter adapter,
String status, String entrance, final OnLibaoStatusChangeListener listener) {
String status, String entrance, String sourceEntrance, final OnLibaoStatusChangeListener listener) {
if ("repeatTao".equals(status)) {
Utils.toast(context, "没到重复淘号时间, 礼包每天0点刷新");
return;
@ -449,6 +492,16 @@ public class LibaoUtils {
des = "您已领取过相同的礼包,可能无法成功兑换";
}
ToastUtils.showToast(des);
SensorsBridge.trackEvent("GameGiftDrawResult",
"draw_result", "成功",
"gift_type", "淘号礼包",
"game_name", libaoEntity.getGame().getName(),
"game_id", libaoEntity.getGame().getId(),
"gift_id", libaoEntity.getId(),
"gift_name", libaoEntity.getName(),
"source_entrance", sourceEntrance
);
}
@Override
@ -507,12 +560,22 @@ public class LibaoUtils {
}
}
Utils.toast(context, "发生异常");
SensorsBridge.trackEvent("GameGiftDrawResult",
"draw_result", "失败",
"gift_type", "淘号礼包",
"game_name", libaoEntity.getGame().getName(),
"game_id", libaoEntity.getGame().getId(),
"gift_id", libaoEntity.getId(),
"gift_name", libaoEntity.getName(),
"source_entrance", sourceEntrance
);
}
});
}
private static void libaoLing(final Context context, TextView libaoBtn, final LibaoEntity libaoEntity, final LibaoDetailAdapter adapter,
final boolean isInstallRequired, String captchaCode, final String entrance, final OnLibaoStatusChangeListener listener) {
final boolean isInstallRequired, String captchaCode, final String entrance, final String sourceEntrance, final OnLibaoStatusChangeListener listener) {
if (BuildConfig.DEBUG) {
if (libaoBtn != null) {
@ -543,6 +606,15 @@ public class LibaoUtils {
}
if (TextUtils.isEmpty(libaoCode)) {
Utils.toast(context, "领取异常");
SensorsBridge.trackEvent("GameGiftDrawResult",
"draw_result", "失败",
"gift_type", "普通礼包",
"game_name", libaoEntity.getGame().getName(),
"game_id", libaoEntity.getGame().getId(),
"gift_id", libaoEntity.getId(),
"gift_name", libaoEntity.getName(),
"source_entrance", sourceEntrance
);
return;
}
libaoEntity.setAvailable(libaoEntity.getAvailable() - 1);
@ -570,6 +642,15 @@ public class LibaoUtils {
}
return null;
});
SensorsBridge.trackEvent("GameGiftDrawResult",
"draw_result", "成功",
"gift_type", "普通礼包",
"game_name", libaoEntity.getGame().getName(),
"game_id", libaoEntity.getGame().getId(),
"gift_id", libaoEntity.getId(),
"gift_name", libaoEntity.getName(),
"source_entrance", sourceEntrance
);
}
@Override
@ -615,7 +696,7 @@ public class LibaoUtils {
}, false, "", "");
libaoEntity.setStatus("used_up");
if (libaoBtn != null) {
initLibaoBtn(context, libaoBtn, libaoEntity, isInstallRequired, adapter, false, entrance, listener);
initLibaoBtn(context, libaoBtn, libaoEntity, isInstallRequired, adapter, false, entrance, sourceEntrance, listener);
}
break;
case "maintaining":
@ -633,13 +714,22 @@ public class LibaoUtils {
} else if (exception.code() == 412) {
// 需要验证
GeetestUtils.getInstance().showDialog(context, captcha ->
libaoLing(context, libaoBtn, libaoEntity, adapter, isInstallRequired, captcha, entrance, listener));
libaoLing(context, libaoBtn, libaoEntity, adapter, isInstallRequired, captcha, entrance, sourceEntrance, listener));
return;
} else if (exception.code() == 401) {
return;
}
}
Utils.toast(context, "发生异常");
SensorsBridge.trackEvent("GameGiftDrawResult",
"draw_result", "失败",
"gift_type", "普通礼包",
"game_name", libaoEntity.getGame().getName(),
"game_id", libaoEntity.getGame().getId(),
"gift_id", libaoEntity.getId(),
"gift_name", libaoEntity.getName(),
"source_entrance", sourceEntrance
);
}
}, captchaCode);
}

View File

@ -1028,7 +1028,7 @@ public class LogUtils {
JSONObject object = new JSONObject();
JSONObject payloadObject = new JSONObject();
try {
object.put(KEY_EVENT, event);//game_gift_get_successful领取礼包、game_gift_dig_successful淘号
object.put(KEY_EVENT, event);//game_gift_get_successful领取礼包、game_gift_dig_successful淘号、game_gift_code_successful复制礼包
payloadObject.put("gift_id", giftId);
payloadObject.put("gift_name", giftName);
payloadObject.put("location", location);

View File

@ -808,13 +808,24 @@ object NewFlatLogUtils {
}
//点击兴趣推荐卡片
fun logDiscoverPageRecommendedInterestCardClick(sequence: Int, linkText: String, linkType: String, linkId: String) {
fun logDiscoverPageRecommendedInterestCardClick(
sequence: Int,
linkText: String,
linkType: String,
linkId: String,
entrance: String,
blockName: String = ""
) {
val json = json {
KEY_EVENT to "discover_page_recommended_interest_card_click"
"sequence" to sequence
"link_text" to linkText
"link_type" to linkType
"link_id" to linkId
"entrance" to entrance
if (blockName.isNotEmpty()) {
"block_name" to blockName
}
parseAndPutMeta().invoke(this)
}
log(json)
@ -1424,4 +1435,171 @@ object NewFlatLogUtils {
}
log(json, "event", false)
}
/**
* 新游开测首页/板块,点击右上角(全部/更多)
*/
fun logGameTestV2MoreClick(
text: String,
location: String,
blockId: String = "",
blockName: String = "",
linkType: String = "",
linkId: String = "",
linkText: String = ""
) {
val json = json {
"event" to "game_test_home_more_click"
"text" to text //右上角文案,包括:全部、更多
"location" to location //新游开测所处位置,包括:首页、版块
"block_id" to blockId //新游开测所处位置为“版块”上报版块ID
"block_name" to blockName //新游开测所处位置为“版块”,上报版块名称
"link_type" to linkType //右上角文案为“更多”时的链接类型
"link_id" to linkId //右上角文案为“更多”时的链接ID
"link_text" to linkText //右上角文案为“更多”时的跳转链接
parseAndPutMeta().invoke(this)
}
log(json, "event", false)
}
/**
* 新游开测首页/板块,点击推荐标签
*/
fun logGameTestV2RecommendLabelClick(
location: String,
blockId: String = "",
blockName: String = "",
tagId: String = "",
text: String = "",
sequence: Int = 0,
linkType: String = "",
linkId: String = "",
linkText: String = ""
) {
val json = json {
"event" to "game_test_home_recommend_tag_click"
"location" to location //新游开测所处位置,包括:首页、版块
"block_id" to blockId //新游开测所处位置为“版块”上报版块ID
"block_name" to blockName //新游开测所处位置为“版块”,上报版块名称
"tag_id" to tagId //点击推荐标签的ID
"text" to text //点击推荐标签的文案
"sequence" to sequence //点击推荐标签在所有标签中所处位置,从左往右依次计算
"link_type" to linkType //点击推荐标签的链接类型
"link_id" to linkId //点击推荐标签的链接ID
"link_text" to linkText //点击推荐标签的跳转链接
parseAndPutMeta().invoke(this)
}
log(json, "event", false)
}
/**
* 新游开测首页点击时间轴
*/
fun logGameTestV2TimeLineClick(
action: String,
type: String,
time: Long,
sequence: Int,
){
val json = json {
"event" to "game_test_home_timeline_click"
"action" to action //类型包括: 1.自动定位:滑动游戏时间轴自动更换定位 2.手动点击:手动点击时间轴的定位
"type" to type //类型包括“推荐/全部”,时间轴定位在“推荐”时记“推荐”,其余位置则记“全部”
"game_test_start" to time //节点时间字符串 2023-03-10 转时间戳
"sequence" to sequence //时间类型为“全部”时时间轴排除“推荐”从左往右依次计算记录在时间轴实际上所处的位置顺序例如12.30排在“推荐”后面则记录“1”
parseAndPutMeta().invoke(this)
}
log(json, "event", false)
}
/**
* 新游开测条目完整展示时长上报
*/
fun logGameTestV2ItemViewTime(
location: String,
blockId: String = "",
blockName: String = "",
interval: Long = 0,
type: String = "",
startTime: Long = 0,
sequence: Int = 0,
){
val json = json {
"event" to "game_test_home_view"
"location" to location //新游开测所处位置,包括:首页、版块
"block_id" to blockId //新游开测所处位置为“版块”上报版块ID
"block_name" to blockName //新游开测所处位置为“版块”,上报版块名称
"interval" to interval //内容在屏幕可见范围完整展示的时长
"type" to type //触发事件时所停留的时间定位;类型包括“推荐/全部”,时间轴定位在“推荐”时记“推荐”,其余位置则记“全部”
"game_test_start" to startTime //触发事件时所停留的时间定位;时间类型为“全部”时,记录具体的月份日期 例如12.30、12.31
"sequence" to sequence //点击推荐标签在所有标签中所处位置,从左往右依次计算
parseAndPutMeta().invoke(this)
}
log(json, "event", false)
}
// gid 变更事件
@JvmStatic
fun logGidChanged(oldGid: String, newGid: String) {
val json = json {
KEY_EVENT to "gid_changed"
"old_gid" to oldGid
"new_gid" to newGid
parseAndPutMeta().invoke(this)
}
log(json)
}
//发现页下拉刷新
fun logDiscoverPageDropDownRefresh(refreshCount: Int) {
val json = json {
"event" to "discover_page_drop_down_refresh"
"count_num" to refreshCount
parseAndPutMeta().invoke(this)
}
log(json, "event", false)
}
//更换头像弹窗点击
fun logChangeAvatarDialogClick(button: String) {
val json = json {
"event" to "profile_picture_change_dialog_click"
"button" to button
parseAndPutMeta().invoke(this)
}
log(json, "event", false)
}
//默认头像弹窗点击
fun logDefaultAvatarDialogClick(button: String) {
val json = json {
"event" to "profile_picture_default_dialog_click"
"button" to button
parseAndPutMeta().invoke(this)
}
log(json, "event", false)
}
fun logVpnHintDialogShow(gameId: String, gameName: String) {
val json = json {
KEY_EVENT to "vpn_pre_access_dialog_show"
KEY_GAME_ID to gameId
KEY_GAME_NAME to gameName
parseAndPutMeta().invoke(this)
}
log(json, "event", false)
}
fun logVpnHintDialogClick(gameId: String, gameName: String, button: String) {
val json = json {
KEY_EVENT to "vpn_pre_access_dialog_click"
KEY_GAME_ID to gameId
KEY_GAME_NAME to gameName
"button" to button
parseAndPutMeta().invoke(this)
}
log(json, "event", false)
}
}

View File

@ -137,7 +137,7 @@ object NewLogUtils {
}
// 游戏详情点击顶部标签
fun logGameDetailTagClick(gameId: String, gameName: String, tagId: String, tagName: String) {
fun logGameDetailTagClick(gameId: String, gameName: String, tagId: String, tagName: String, isTop: Boolean) {
val json = json {
KEY_EVENT to "game_type_tag_click_jump"
KEY_META to LogUtils.getMetaObject()
@ -145,6 +145,7 @@ object NewLogUtils {
KEY_GAME_NAME to gameName
"type_tag_id" to tagId
"type_tag_name" to tagName
"is_top_type_tag" to isTop
KEY_TIMESTAMP to System.currentTimeMillis() / 1000
}
log(json, LOG_STORE_EVENT)

View File

@ -1,11 +1,11 @@
package com.gh.common.util
import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Build
import android.view.View
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.FileProvider
import com.gh.common.dialog.InstallPermissionDialogFragment
@ -13,25 +13,18 @@ import com.gh.common.xapk.XapkInstaller
import com.gh.download.server.BrowserInstallHelper
import com.gh.gamecenter.BuildConfig
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.common.utils.DialogHelper
import com.gh.gamecenter.common.utils.getExtension
import com.gh.gamecenter.common.utils.getMetaExtra
import com.gh.gamecenter.common.utils.toRequestBody
import com.gh.gamecenter.core.utils.CurrentActivityHolder
import com.gh.gamecenter.core.utils.MD5Utils
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.retrofit.RetrofitManager
import com.gh.gamecenter.vpn.VpnHelper
import com.gh.vspace.VHelper
import com.halo.assistant.HaloApp
import com.lightgame.download.DownloadEntity
import com.lightgame.download.FileUtils
import com.lightgame.utils.Utils
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
import okhttp3.ResponseBody
import retrofit2.HttpException
import java.io.File
object PackageInstaller {
@ -64,15 +57,17 @@ object PackageInstaller {
return
}
// TODO 此处可能遇到 activity 是 WXEntryActivity
// TODO 当 activity 全部出栈,但是应用还在下载游戏,下载完会唤不起安装!
// 已知问题
// 1. 此处可能遇到 activity 是 WXEntryActivity因为 WXEntryActivity 不是 AppCompatActivity 调不起弹窗
// 2. 当 activity 全部出栈,但是应用还在下载游戏,下载完会唤不起安装
if (currentActivity is AppCompatActivity && !currentActivity.isFinishing) {
InstallPermissionDialogFragment.show(currentActivity, downloadEntity) { isFromPermissionGrantedCallback ->
// 取消状态栏下载完成的通知,若存在
downloadEntity.meta[Constants.MARK_ALREADY_TRIGGERED_INSTALLATION] = "YES"
DownloadNotificationHelper.addOrUpdateDownloadNotification(downloadEntity)
if (isFromPermissionGrantedCallback && Build.VERSION.SDK_INT >= 31) {
// 安卓12后的设备需要重启应用来继续解压 XAPK 文件
if (isFromPermissionGrantedCallback && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
val pm = context.packageManager
val intent = pm.getLaunchIntentForPackage(context.packageName)
val mainIntent = Intent.makeRestartActivityTask(intent!!.component)
@ -82,7 +77,7 @@ object PackageInstaller {
if (isXapk) {
XapkInstaller.install(context, downloadEntity, showUnzipToast)
} else {
install(context, downloadEntity.isPlugin, downloadEntity.path)
install(context, downloadEntity.isPlugin, downloadEntity.path, downloadEntity)
}
}
}
@ -94,9 +89,11 @@ object PackageInstaller {
*
* 除非特殊情况,请勿使用此方法进行应用安装操作
* 除非你已经确定该文件一定是Apk
*
* @param downloadEntity 仅用来记录日志用,非必须可为空
*/
@JvmStatic
fun install(context: Context, isPluggin: Boolean = false, pkgPath: String?) {
fun install(context: Context, isPluggin: Boolean = false, pkgPath: String?, downloadEntity: DownloadEntity? = null) {
if (pkgPath.isNullOrEmpty()) {
ToastUtils.toast("下载文件异常")
return
@ -112,20 +109,13 @@ object PackageInstaller {
}
if (PackageUtils.isCanLaunchSetup(context, pkgPath)) {
// val app = HaloApp.getInstance()
val currentActivity = CurrentActivityHolder.getCurrentActivity()
HaloApp.put(Constants.LAST_INSTALL_GAME, pkgPath)
// val downloadEntity =
// DownloadManager.getInstance().allDownloadEntity.firstOrNull {
// it.path == pkgPath
// }
// if (downloadEntity != null) {
// showCertificateDialogIfNeededBeforeInstall(app, downloadEntity, pkgPath)
// } else {
val installIntent = getInstallIntent(context, pkgPath)
context.startActivity(installIntent)
// }
if (VpnHelper.shouldUseVpn() && currentActivity is AppCompatActivity) {
turnOnVpnThenInstall(currentActivity, pkgPath, downloadEntity)
} else {
install(context, pkgPath)
}
} else {
if (isPluggin) {
DialogHelper.showPluginDialog(context) {
@ -143,47 +133,13 @@ object PackageInstaller {
}
}
@SuppressLint("CheckResult")
fun showCertificateDialogIfNeededBeforeInstall(context: Context, downloadEntity: DownloadEntity, pkgPath: String) {
val isOverwrite = LunchType.UPDATE.name == SPUtils.getString(Constants.SP_INSTALL_TYPE)
val hashMap = hashMapOf(Pair("url", downloadEntity.url), Pair("overwrite", isOverwrite))
RetrofitManager.getInstance().api.postCertificationCheck(hashMap.toRequestBody())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : BiResponse<ResponseBody>() {
override fun onSuccess(data: ResponseBody) {
val installIntent = getInstallIntent(context, pkgPath)
context.startActivity(installIntent)
}
override fun onFailure(exception: Exception) {
super.onFailure(exception)
if (exception is HttpException) {
val resultString =
(exception as HttpException).response().errorBody()
?.string()
// 未实名
when {
resultString?.contains("403117") == true -> {
RealNameHelper.showRealNameUncertificatedDialog(
downloadEntity
)
}
resultString?.contains("403118") == true -> {
RealNameHelper.showRealNameUnqualifiedDialog(
downloadEntity
)
}
resultString?.contains("400004") == true -> {
ToastUtils.toast("安装服务异常,缺少参数")
}
}
} else {
ToastUtils.toast("安装服务异常,${exception.localizedMessage}请稍候再试")
}
}
})
/**
* 最终执行安装的方法
*/
private fun install(context: Context, pkgPath: String) {
HaloApp.put(Constants.LAST_INSTALL_GAME, pkgPath)
val installIntent = getInstallIntent(context, pkgPath)
context.startActivity(installIntent)
}
/**
@ -271,4 +227,81 @@ object PackageInstaller {
fun createDownloadId(gameName: String?): String {
return MD5Utils.getContentMD5(gameName + "_" + System.currentTimeMillis())
}
/**
* 启动 VPN 然后安装应用 (若没有授权会先提醒授权 VPN ,若拒绝授权会回落到直接执行安装)
*/
private fun turnOnVpnThenInstall(currentActivity: AppCompatActivity,
pkgPath: String,
downloadEntity: DownloadEntity?) {
if (VpnHelper.isVpnPermissionGranted(currentActivity) == true) {
VpnHelper.startVpn(currentActivity) { shouldShowVpnError ->
if (shouldShowVpnError) {
ToastUtils.toast("安装防护功能启动失败")
}
install(currentActivity, pkgPath)
}
} else {
val isTheFirstTimeToShowVpnHintDialog = VpnHelper.isTheFistTimeToShowVpnHintDialog()
downloadEntity?.let {
NewFlatLogUtils.logVpnHintDialogShow(it.gameId, it.name)
}
// 将 VPN 提示弹窗标记为已读(已读后的下一次显示"不再提醒"按钮)
VpnHelper.setVpnHintDialogShowed()
if (!VpnHelper.shouldShowVpnHintDialog()) {
VpnHelper.startVpn(currentActivity) { shouldShowVpnError ->
if (shouldShowVpnError) {
ToastUtils.toast("安装防护功能启动失败")
}
install(currentActivity, pkgPath)
}
} else {
DialogHelper.showGuideDialog(
context = currentActivity,
title = "开启安装防护",
content = "建议您开启安装防护功能该功能有助于帮助您更快的完成安装避免因提示和置换导致的重复下载等问题安装防护功能需要获取您的VPN权限",
confirmText = "立即授权开启防护",
cancelText = "不再提醒",
confirmClickCallback = {
VpnHelper.ignoreVpnHintDialog()
VpnHelper.startVpn(currentActivity) { shouldShowVpnError ->
if (shouldShowVpnError) {
ToastUtils.toast("安装防护功能启动失败")
}
install(currentActivity, pkgPath)
}
downloadEntity?.let {
NewFlatLogUtils.logVpnHintDialogClick(it.gameId, it.name, "立即授权")
}
},
cancelClickCallback = {
VpnHelper.ignoreVpnFunction()
install(currentActivity, pkgPath)
downloadEntity?.let {
NewFlatLogUtils.logVpnHintDialogClick(it.gameId, it.name, "不再提醒")
}
},
extraConfig = DialogHelper.Config(
showCloseIcon = true,
showAlternativeCancelStyle = !isTheFirstTimeToShowVpnHintDialog
),
uiModificationCallback = { binding, dialog ->
binding.cancelTv.visibility = View.GONE
binding.closeContainer.setOnClickListener {
install(currentActivity, pkgPath)
dialog.dismiss()
downloadEntity?.let {
NewFlatLogUtils.logVpnHintDialogClick(it.gameId, it.name, "关闭按钮")
}
}
}
)
}
}
}
}

View File

@ -23,6 +23,7 @@ import androidx.webkit.WebViewCompat;
import com.android.apksig.ApkVerifier;
import com.android.apksig.internal.apk.ApkSigningBlockUtilsLite;
import com.g00fy2.versioncompare.Version;
import com.gh.common.filter.RegionSettingHelper;
import com.gh.common.xapk.XapkInstaller;
import com.gh.gamecenter.BuildConfig;
import com.gh.gamecenter.common.constant.Constants;
@ -139,6 +140,11 @@ public class PackageUtils {
}
}
// 镜像游戏,使用镜像 Apk 替换掉原来的 ApkNormal
if (RegionSettingHelper.shouldThisGameDisplayMirrorInfo(gameEntity.getId())) {
gameEntity.setApkNormal(gameEntity.getApk());
}
// 非插件游戏更新
for (ApkEntity apkEntity : gameEntity.getApkNormal()) {

View File

@ -3,8 +3,10 @@ package com.gh.common.util
import com.gh.gamecenter.core.utils.CurrentActivityHolder
import com.gh.download.DownloadManager
import com.gh.gamecenter.ShellActivity
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.utils.DialogHelper
import com.gh.gamecenter.common.utils.SensorsBridge
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.common.utils.getMetaExtra
import com.lightgame.download.DownloadEntity
@ -54,6 +56,15 @@ object RealNameHelper {
val isForced = downloadEntity.getMetaExtra("force_real_name") != "false"
NewLogUtils.logCertificationTrigger(downloadEntity.gameId, downloadEntity.name)
SensorsBridge.trackEvent(
"VerificationDialogShow",
"game_id",
downloadEntity.gameId,
"game_name",
downloadEntity.name ?: "",
"game_type",
downloadEntity.meta[Constants.GAME_TYPE] ?: ""
)
val contentText = if (downloadEntity.status == DownloadStatus.done) {
"为保护未成年身心健康成长\n" + "根据相关政策要求,该游戏不对未成年人开放\n" + "如需完成安装,请前往实名认证"
@ -88,9 +99,11 @@ object RealNameHelper {
pendingInstallPkgPath = downloadEntity.path
}
NewLogUtils.logCertificationHintDialogOptionsClicked("前往实名认证")
SensorsBridge.trackEvent("VerificationPopupClick", "button_name", "前往实名认证")
},
cancelClickCallback = {
NewLogUtils.logCertificationHintDialogOptionsClicked("取消")
SensorsBridge.trackEvent("VerificationPopupClick", "button_name", "取消")
if (!isForced) {
DownloadManager.getInstance()
.resumeAllInvisiblePendingTask()

View File

@ -69,7 +69,7 @@ object ReservationHelper {
@JvmStatic
@SuppressLint("CheckResult")
fun reserve(context: Context, gameId: String, callback: EmptyCallback) {
fun reserve(context: Context, gameId: String, gameName: String, callback: EmptyCallback) {
val requestMap = hashMapOf<String, String>()
requestMap["game_id"] = gameId
RetrofitManager.getInstance().api
@ -78,6 +78,16 @@ object ReservationHelper {
.subscribe(object : BiResponse<ResponseBody>() {
override fun onSuccess(data: ResponseBody) {
SensorsBridge.trackEvent(
"AppointmentGameResult",
"game_name",
gameName,
"game_id",
gameId,
"result",
"成功"
)
ReservationRepository.addReservationToMemoryAndRefresh(gameId)
callback.onCallback()
val wechatConfig = SPUtils.getString(Constants.SP_WECHAT_CONFIG).toObject<WechatConfigEntity>()
@ -88,14 +98,22 @@ object ReservationHelper {
DialogUtils.showReserveSuccessDialog(context)
} else {
NewLogUtils.logReserveWechatRemindPopShow(wechatConfig)
SensorsBridge.trackEvent("AppointmenWechatRemindDialogShow")
DialogUtils.showReserveSuccess2WechatBindDialog(context, object : ConfirmListener {
override fun onConfirm() {
NewLogUtils.logReserveWechatRemindPopClick(wechatConfig, "开启微信提醒")
SensorsBridge.trackEvent("AppointmenWechatRemindDialogClick")
context.startActivity(WebActivity.getBindWechatIntent(context))
SensorsBridge.trackEvent(
"AppointmenWechatRemindConfigPageShow",
"source_entrance",
"设置微信提醒弹窗"
)
}
}, object : CancelListener {
override fun onCancel() {
NewLogUtils.logReserveWechatRemindPopClick(wechatConfig, "关闭弹窗")
SensorsBridge.trackEvent("AppointmenWechatRemindDialogClick")
}
})
}
@ -103,6 +121,15 @@ object ReservationHelper {
}
override fun onFailure(exception: Exception) {
SensorsBridge.trackEvent(
"AppointmentGameResult",
"game_name",
gameName,
"game_id",
gameId,
"result",
"失败"
)
ToastUtils.showToast(exception.message ?: "")
}
})

View File

@ -12,10 +12,7 @@ import android.widget.LinearLayout
import android.widget.TextView
import androidx.core.content.ContextCompat
import com.gh.gamecenter.R
import com.gh.gamecenter.common.utils.DarkModeUtils
import com.gh.gamecenter.common.utils.dip2px
import com.gh.gamecenter.common.utils.sp2px
import com.gh.gamecenter.common.utils.toColor
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.feature.entity.TagStyleEntity
import kotlin.math.ceil
@ -41,12 +38,12 @@ class FlexLinearLayout @JvmOverloads constructor(context: Context, attrs: Attrib
gravity = Gravity.CENTER_VERTICAL
val ta = context.obtainStyledAttributes(attrs, R.styleable.FlexLinearLayout)
mItemHeight = ta.getDimensionPixelSize(R.styleable.FlexLinearLayout_itemHeight, 20f.dip2px())
mPadding = ta.getDimensionPixelSize(R.styleable.FlexLinearLayout_itemPadding, 5f.dip2px())
mMargin = ta.getDimensionPixelSize(R.styleable.FlexLinearLayout_itemMargin, 4f.dip2px())
mTextSize = ta.getDimension(R.styleable.FlexLinearLayout_itemTextSize, 10f.sp2px().toFloat())
mLastItemWidth = ta.getDimensionPixelSize(R.styleable.FlexLinearLayout_lastItemWidth, 18f.dip2px())
mStrokeWidth = ta.getDimensionPixelSize(R.styleable.FlexLinearLayout_strokeWidth, 0.5f.dip2px())
mItemHeight = ta.getDimensionPixelSize(R.styleable.FlexLinearLayout_itemHeight, 20F.dip2px())
mPadding = ta.getDimensionPixelSize(R.styleable.FlexLinearLayout_itemPadding, 5F.dip2px())
mMargin = ta.getDimensionPixelSize(R.styleable.FlexLinearLayout_itemMargin, 4F.dip2px())
mTextSize = ta.getDimension(R.styleable.FlexLinearLayout_itemTextSize, 10F.sp2px().toFloat())
mLastItemWidth = ta.getDimensionPixelSize(R.styleable.FlexLinearLayout_lastItemWidth, 18F.dip2px())
mStrokeWidth = ta.getDimensionPixelSize(R.styleable.FlexLinearLayout_strokeWidth, 0.5F.dip2px())
ta.recycle()
}
@ -95,7 +92,7 @@ class FlexLinearLayout @JvmOverloads constructor(context: Context, attrs: Attrib
layoutParams = params
setImageDrawable(ContextCompat.getDrawable(context, R.drawable.ic_game_detail_label_more))
if (DarkModeUtils.isDarkModeOn(context)) setColorFilter(R.color.text_title.toColor(context))
background = createBackgroundDrawable()
background = createNormalBackgroundDrawable()
scaleType = ImageView.ScaleType.CENTER
}
imageView.setOnClickListener {
@ -111,27 +108,33 @@ class FlexLinearLayout @JvmOverloads constructor(context: Context, attrs: Attrib
includeFontPadding = false
textSize = DisplayUtils.px2sp(context, mTextSize).toFloat()
gravity = Gravity.CENTER
setTextColor(R.color.text_title.toColor(context))
val params = LayoutParams(LayoutParams.WRAP_CONTENT, mItemHeight)
params.setMargins(0, 0, mMargin, 0)
setPadding(mPadding, 0, mPadding, 0)
layoutParams = params
val gradientDrawable = createBackgroundDrawable()
background = gradientDrawable
setTextColor(if (tag.isTop) "#${tag.color}".hexStringToIntColor() else R.color.text_title.toColor(context))
background = if (tag.isTop) createTopBackgroundDrawable(tag) else createNormalBackgroundDrawable()
setOnClickListener {
onClickListener?.onItemClickListener(tag)
}
}
}
private fun createBackgroundDrawable(): GradientDrawable {
private fun createNormalBackgroundDrawable(): GradientDrawable {
val gradientDrawable = GradientDrawable()
val isDarkModeOn = DarkModeUtils.isDarkModeOn(context)
gradientDrawable.setColor(Color.TRANSPARENT)
gradientDrawable.setStroke(mStrokeWidth, Color.parseColor(if (isDarkModeOn) "#33FFFFFF" else "#CCCCCC"))
gradientDrawable.cornerRadius = DisplayUtils.dip2px(2f).toFloat()
gradientDrawable.cornerRadius = 2F.dip2px().toFloat()
return gradientDrawable
}
private fun createTopBackgroundDrawable(tag: TagStyleEntity): GradientDrawable {
val gradientDrawable = GradientDrawable()
gradientDrawable.setColor("#${tag.background}".hexStringToIntColor())
gradientDrawable.cornerRadius = 2F.dip2px().toFloat()
return gradientDrawable
}

View File

@ -22,6 +22,7 @@ import com.gh.gamecenter.common.utils.DialogHelper;
import com.gh.gamecenter.common.utils.EnvHelper;
import com.gh.gamecenter.common.utils.ExtensionsKt;
import com.gh.gamecenter.common.utils.ImageUtils;
import com.gh.gamecenter.common.utils.NetworkUtils;
import com.gh.gamecenter.core.utils.DisplayUtils;
import com.gh.gamecenter.core.utils.EmptyCallback;
import com.gh.gamecenter.core.utils.GsonUtils;
@ -139,6 +140,7 @@ public class RichEditor extends WebView {
setVerticalScrollBarEnabled(false);
setHorizontalScrollBarEnabled(false);
getSettings().setJavaScriptEnabled(true);
getSettings().setDomStorageEnabled(true);
setWebChromeClient(new WebChromeClient()); // 不要重写这个方法否则无法加载
setWebViewClient(createWebViewClient());
@ -573,6 +575,13 @@ public class RichEditor extends WebView {
exec("javascript:RE.formatBlock();");
}
/**
* 调用 JS 方法,告诉网页端该 url 对应视频播放的进度
*/
public void onVideoPlayedCallback(String url, int position) {
exec("javascript:RE.onVideoPlayedCallback('" + url + "', '" + position + "')");
}
public String getText() {
return HtmlUtils.stripHtml(mContents);
}
@ -586,7 +595,7 @@ public class RichEditor extends WebView {
return String.format("#%06X", (0xFFFFFF & color));
}
protected void exec(final String trigger) {
public void exec(final String trigger) {
if (isReady) {
load(trigger);
} else {
@ -708,7 +717,9 @@ public class RichEditor extends WebView {
@JavascriptInterface
public void onPageFinished() {
mPageFinishedListener.onPageFinished();
if (mPageFinishedListener != null) {
mPageFinishedListener.onPageFinished();
}
}
@JavascriptInterface
@ -721,6 +732,16 @@ public class RichEditor extends WebView {
return PackageUtils.getGhVersionCode();
}
@JavascriptInterface
public boolean isNetworkConnected() {
return NetworkUtils.isNetworkConnected(HaloApp.getInstance());
}
@JavascriptInterface
public boolean isWifiConnected() {
return NetworkUtils.isWifiConnected(HaloApp.getInstance());
}
/**
* 显示toast
*

View File

@ -1,16 +1,17 @@
package com.gh.common.xapk
import android.content.Context
import com.gh.gamecenter.core.AppExecutor
import com.gh.common.util.*
import com.gh.common.util.DownloadNotificationHelper
import com.gh.common.util.PackageInstaller
import com.gh.download.DownloadManager
import com.gh.gamecenter.common.utils.debugOnly
import com.gh.gamecenter.common.utils.getExtension
import com.gh.gamecenter.common.utils.throwExceptionInDebug
import com.gh.gamecenter.common.utils.tryCatchInRelease
import com.gh.gamecenter.core.AppExecutor
import com.gh.gamecenter.core.utils.SentryHelper
import com.gh.ndownload.NDataChanger
import com.halo.assistant.HaloApp
import com.lightgame.download.DataChanger
import com.lightgame.download.DownloadEntity
import com.lightgame.utils.Utils
import java.text.DecimalFormat
@ -81,7 +82,7 @@ object XapkInstaller : IXapkUnzipListener {
}
downloadEntity.meta[XAPK_UNZIP_PERCENT] = percent.toString()
downloadEntity.meta[XAPK_UNZIP_STATUS] = XapkUnzipStatus.UNZIPPING.name
DataChanger.notifyDataChanged(downloadEntity)
NDataChanger.notifyDataChanged(downloadEntity)
}
debugOnly {
@ -111,7 +112,7 @@ object XapkInstaller : IXapkUnzipListener {
AppExecutor.uiExecutor.execute {
downloadEntity.meta[XAPK_UNZIP_PERCENT] = "0.0"
downloadEntity.meta[XAPK_UNZIP_STATUS] = XapkUnzipStatus.CANCEL.name
DataChanger.notifyDataChanged(downloadEntity)
NDataChanger.notifyDataChanged(downloadEntity)
DownloadManager.getInstance().updateDownloadEntity(downloadEntity)
}
}
@ -122,7 +123,7 @@ object XapkInstaller : IXapkUnzipListener {
AppExecutor.uiExecutor.execute {
downloadEntity.meta[XAPK_UNZIP_STATUS] = XapkUnzipStatus.FAILURE.name
DownloadNotificationHelper.addOrUpdateDownloadNotification(downloadEntity)
DataChanger.notifyDataChanged(downloadEntity)
NDataChanger.notifyDataChanged(downloadEntity)
DownloadManager.getInstance().updateDownloadEntity(downloadEntity)
}
@ -152,11 +153,11 @@ object XapkInstaller : IXapkUnzipListener {
return@execute
}
PackageInstaller.install(mContext, downloadEntity.isPlugin, pkgPath)
PackageInstaller.install(mContext, downloadEntity.isPlugin, pkgPath, downloadEntity)
downloadEntity.meta[XAPK_UNZIP_PERCENT] = "100.0"
downloadEntity.meta[XAPK_UNZIP_STATUS] = XapkUnzipStatus.SUCCESS.name
DataChanger.notifyDataChanged(downloadEntity)
NDataChanger.notifyDataChanged(downloadEntity)
DownloadManager.getInstance().updateDownloadEntity(downloadEntity)
}

View File

@ -13,8 +13,8 @@ import com.gh.gamecenter.common.utils.getExtension
import com.gh.gamecenter.common.utils.getMetaExtra
import com.gh.gamecenter.common.utils.isSimulatorGame
import com.gh.gamecenter.core.utils.SentryHelper
import com.gh.ndownload.NDataChanger
import com.halo.assistant.HaloApp
import com.lightgame.download.DataChanger
import com.lightgame.download.DownloadConfig
import com.lightgame.download.DownloadEntity
import com.lightgame.download.DownloadStatus
@ -128,6 +128,7 @@ object DownloadDataHelper {
payloadObject.put("platform", downloadEntity.platform)
payloadObject.put("package", downloadEntity.packageName)
payloadObject.put("filename", getFileName(downloadEntity))
payloadObject.put("task_num", NDataChanger.downloadingTasks.size)
jsonObject.put("payload", payloadObject)
} catch (e: Exception) {
e.printStackTrace()
@ -202,6 +203,8 @@ object DownloadDataHelper {
// payload
val payloadObject = JSONObject()
val parallel = downloadEntity.meta[DOWNLOAD_THREAD_SIZE]?.toInt()
payloadObject.put("host", downloadEntity.meta[DownloadEntity.DOWNLOAD_HOST_KEY] ?: "unknown")
payloadObject.put("path", downloadEntity.meta[DownloadEntity.DOWNLOAD_PATH_KEY] ?: "unknown")
payloadObject.put("game_id", downloadEntity.gameId)
@ -210,7 +213,10 @@ object DownloadDataHelper {
payloadObject.put("package", downloadEntity.packageName)
payloadObject.put("filename", getFileName(downloadEntity))
payloadObject.put("launch_ms", startupTime)
payloadObject.put("parallel", downloadEntity.meta[DOWNLOAD_THREAD_SIZE]?.toInt() ?: 0)
payloadObject.put("task_num", NDataChanger.downloadingTasks.size)
if (parallel != null) {
payloadObject.put("parallel", parallel)
}
jsonObject.put("payload", payloadObject)
} catch (e: Exception) {
e.printStackTrace()
@ -234,7 +240,9 @@ object DownloadDataHelper {
// payload
val payloadObject = JSONObject()
val parallel = downloadEntity.meta[DOWNLOAD_THREAD_SIZE]?.toInt()
val sizeInMB = downloadEntity.size / 1024 / 1024
payloadObject.put("host", downloadEntity.meta[DownloadEntity.DOWNLOAD_HOST_KEY] ?: "unknown")
payloadObject.put("path", downloadEntity.meta[DownloadEntity.DOWNLOAD_PATH_KEY] ?: "unknown")
payloadObject.put("game_id", downloadEntity.gameId)
@ -243,7 +251,9 @@ object DownloadDataHelper {
payloadObject.put("package", downloadEntity.packageName)
payloadObject.put("filename", getFileName(downloadEntity))
payloadObject.put("total_size", sizeInMB)
payloadObject.put("parallel", downloadEntity.meta[DOWNLOAD_THREAD_SIZE]?.toInt() ?: 0)
if (parallel != null) {
payloadObject.put("parallel", parallel)
}
if (statusAlias == "下载完成") {
val elapsedTimeString = downloadEntity.meta[DownloadConfig.KEY_DOWNLOAD_ELAPSED_TIME]
@ -264,7 +274,7 @@ object DownloadDataHelper {
payloadObject.put("speed", speed)
}
} else {
payloadObject.put("task_num", DataChanger.downloadingTasks.size)
payloadObject.put("task_num", NDataChanger.downloadingTasks.size)
}
payloadObject.put("completed_size", downloadEntity.progress / 1024 / 1024)
if (downloadEntity.status == DownloadStatus.resume) {
@ -301,6 +311,8 @@ object DownloadDataHelper {
// payload
val payloadObject = JSONObject()
val parallel = downloadEntity.meta[DOWNLOAD_THREAD_SIZE]?.toInt()
payloadObject.put("host", downloadEntity.meta[DownloadEntity.DOWNLOAD_HOST_KEY] ?: "unknown")
payloadObject.put("path", downloadEntity.meta[DownloadEntity.DOWNLOAD_PATH_KEY] ?: "unknown")
payloadObject.put("game_id", downloadEntity.gameId)
@ -311,8 +323,10 @@ object DownloadDataHelper {
payloadObject.put("speed_progress", JSONArray(averageSpeedList))
payloadObject.put("is_finished", downloadEntity.status == DownloadStatus.done)
payloadObject.put("completed_size", downloadEntity.progress / 1024 / 1024)
payloadObject.put("parallel", downloadEntity.meta[DOWNLOAD_THREAD_SIZE]?.toInt() ?: 0)
payloadObject.put("task_num", DataChanger.downloadingTasks.size)
if (parallel != null) {
payloadObject.put("parallel", parallel)
}
payloadObject.put("task_num", NDataChanger.downloadingTasks.size)
jsonObject.put("payload", payloadObject)
} catch (e: Exception) {
e.printStackTrace()
@ -335,7 +349,7 @@ object DownloadDataHelper {
* 在后台唤醒的情况下 下载状态可能无法修正
* see [DownloadManager.initDownloadService]
*/
if (downloadEntity.status == DownloadStatus.downloading && DataChanger.downloadingTasks[downloadEntity.url] != null) {
if (downloadEntity.status == DownloadStatus.downloading && NDataChanger.downloadingTasks[downloadEntity.url] != null) {
var sheet = mDownloadHeartbeatSheet[downloadEntity.url]
if (sheet == null) {
sheet = JSONObject()

View File

@ -15,7 +15,9 @@ import androidx.collection.ArrayMap;
import androidx.lifecycle.LiveData;
import androidx.lifecycle.MutableLiveData;
import com.gh.gamecenter.common.base.GlobalActivityManager;
import com.gh.gamecenter.common.utils.ExtensionsKt;
import com.gh.gamecenter.common.utils.SensorsBridge;
import com.gh.gamecenter.core.AppExecutor;
import com.gh.gamecenter.common.constant.Constants;
import com.gh.gamecenter.feature.exposure.ExposureEvent;
@ -47,17 +49,17 @@ import com.gh.gamecenter.eventbus.EBDownloadStatus;
import com.gh.gamecenter.manager.PackagesManager;
import com.gh.gamecenter.login.user.UserManager;
import com.gh.gamecenter.packagehelper.PackageRepository;
import com.gh.ndownload.NDataChanger;
import com.gh.ndownload.NDownloadBridge;
import com.gh.ndownload.NDownloadService;
import com.halo.assistant.HaloApp;
import com.lightgame.download.ConnectionUtils;
import com.lightgame.download.DataChanger;
import com.lightgame.download.DataWatcher;
import com.lightgame.download.DownloadConfig;
import com.lightgame.download.DownloadDao;
import com.lightgame.download.DownloadEntity;
import com.lightgame.download.DownloadService;
import com.lightgame.download.DownloadStatus;
import com.lightgame.download.DownloadStatusListener;
import com.lightgame.download.DownloadStatusManager;
import com.lightgame.download.DownloadTask;
import com.lightgame.download.FileUtils;
import com.lightgame.download.HttpDnsManager;
@ -89,9 +91,9 @@ public class DownloadManager implements DownloadStatusListener {
private final Map<String, ConcurrentHashMap<String, DownloadEntity>> gameMap;
private final ArrayMap<String, DownloadStatus> statusMap;
private final ArrayMap<String, DownloadEntity> downloadingMap;
private final ConcurrentHashMap<String, DownloadEntity> downloadingMap;
private ArrayList<DownloadEntity> mInvisiblePendingTaskList; // 用户不可见的 pending 任务
private final ArrayList<DownloadEntity> mInvisiblePendingTaskList; // 用户不可见的 pending 任务
private final DownloadDao mDownloadDao;
private final DownloadedGameIdAndPackageNameDao mDownloadedGameIdAndPackageNameDao;
@ -167,8 +169,6 @@ public class DownloadManager implements DownloadStatusListener {
mUpdateMarks = SPUtils.getStringSet(UPDATE_IS_READ_MARK);
DownloadStatusManager.getInstance().registerTaskStatusListener(this);
// 只有下载模块需要这坨东西,因此移动到这里初始化
ConnectionUtils.initHttpsUrlConnection(mContext);
@ -178,7 +178,7 @@ public class DownloadManager implements DownloadStatusListener {
platformMap = new ArrayMap<>();
gameMap = new ConcurrentHashMap<>();
statusMap = new ArrayMap<>();
downloadingMap = new ArrayMap<>();
downloadingMap = new ConcurrentHashMap<>();
// mDownloadSnapshotList = new ArrayList<>();
mInvisiblePendingTaskList = new ArrayList<>();
@ -224,10 +224,6 @@ public class DownloadManager implements DownloadStatusListener {
}
}
public ArrayMap<String, DownloadEntity> getDownloadingMap() {
return downloadingMap;
}
public static DownloadManager getInstance() {
return SingletonHolder.INSTANCE;
}
@ -326,6 +322,9 @@ public class DownloadManager implements DownloadStatusListener {
ExtensionsKt.addMetaExtra(downloadEntity, Constants.GAME_ICON_SUBSCRIPT, gameEntity.getIconSubscript());
ExtensionsKt.addMetaExtra(downloadEntity, Constants.IS_PLATFORM_RECOMMEND, apkEntity.getRecommend() != null ? "true" : "false");
ExtensionsKt.addMetaExtra(downloadEntity, Constants.GAME_NAME, gameEntity.getName());
ExtensionsKt.addMetaExtra(downloadEntity, Constants.GAME_TYPE, gameEntity.getCategoryChinese());
ExtensionsKt.addMetaExtra(downloadEntity, Constants.AD_ICON_ACTIVE, String.valueOf(gameEntity.getAdIconActive()));
ExtensionsKt.addMetaExtra(downloadEntity, Constants.IS_AD_DATA, String.valueOf(gameEntity.isAdData()));
if (gameEntity.getIconFloat() != null) {
ExtensionsKt.addMetaExtra(downloadEntity, Constants.GAME_ICON_FLOAT_TOP_TEXT, gameEntity.getIconFloat().getUpperLeftText());
ExtensionsKt.addMetaExtra(downloadEntity, Constants.GAME_ICON_FLOAT_TOP_COLOR, gameEntity.getIconFloat().getUpperLeftColor());
@ -340,6 +339,22 @@ public class DownloadManager implements DownloadStatusListener {
ExtensionsKt.addMetaExtra(downloadEntity, Constants.SMOOTH_GAME, "true");
ExtensionsKt.addMetaExtra(downloadEntity, Constants.EXTRA_DOWNLOAD_TYPE, Constants.SMOOTH_GAME);
ExtensionsKt.addMetaExtra(downloadEntity, DownloadConfig.KEY_PROGRESS_CALLBACK_INTERVAL, "200");
SensorsBridge.trackEvent("HaloFunGameDownloadClick",
"game_name", gameEntity.getName(),
"game_id", gameEntity.getId());
} else {
SensorsBridge.trackEvent("DownloadProcessBegin",
"game_id", gameEntity.getId(),
"game_name", gameEntity.getName(),
"game_type", gameEntity.getCategoryChinese(),
"page_name", GlobalActivityManager.getCurrentPageEntity().getPageName(),
"page_id", GlobalActivityManager.getCurrentPageEntity().getPageId(),
"page_business_id", GlobalActivityManager.getCurrentPageEntity().getPageBusinessId(),
"last_page_name", GlobalActivityManager.getLastPageEntity().getPageName(),
"last_page_id", GlobalActivityManager.getLastPageEntity().getPageId(),
"last_page_business_id", GlobalActivityManager.getLastPageEntity().getPageBusinessId()
);
}
HashMap<String, String> map = PageSwitchDataHelper.popLastPageData();
@ -423,7 +438,7 @@ public class DownloadManager implements DownloadStatusListener {
if (isDownloadCompleted(url)) {
downloadEntity.setStatus(DownloadStatus.done);
DataChanger.INSTANCE.notifyDataChanged(downloadEntity);
NDataChanger.INSTANCE.notifyDataChanged(downloadEntity);
} else if (!isTaskDownloading(url)) {
startDownloadService(downloadEntity, DownloadStatus.add);
}
@ -444,7 +459,7 @@ public class DownloadManager implements DownloadStatusListener {
checkDownloadEntryRecordValidate(url);
if (isDownloadCompleted(url)) {
downloadEntity.setStatus(DownloadStatus.done);
DataChanger.INSTANCE.notifyDataChanged(downloadEntity);
NDataChanger.INSTANCE.notifyDataChanged(downloadEntity);
} else if (!isTaskDownloading(url)) {
DownloadEntity daoEntity = mDownloadDao.get(downloadEntity.getUrl());
if (automatic) {
@ -479,7 +494,7 @@ public class DownloadManager implements DownloadStatusListener {
checkDownloadEntryRecordValidate(url);
if (isDownloadCompleted(url)) {
downloadEntity.setStatus(DownloadStatus.done);
DataChanger.INSTANCE.notifyDataChanged(downloadEntity);
NDataChanger.INSTANCE.notifyDataChanged(downloadEntity);
} else if (!isTaskDownloading(url)) {
startDownloadService(downloadEntity, DownloadStatus.subscribe);
}
@ -525,7 +540,7 @@ public class DownloadManager implements DownloadStatusListener {
* 任务是否已经下载中
*/
public boolean isTaskDownloading(String url) {
if (DataChanger.INSTANCE.getDownloadingTasks().get(url) != null) {
if (NDataChanger.INSTANCE.getDownloadingTasks().get(url) != null) {
Utils.log(DownloadManager.class.getSimpleName(), url + "正在下载!");
return true;
}
@ -533,7 +548,7 @@ public class DownloadManager implements DownloadStatusListener {
}
private Intent getIntent(DownloadEntity entry, DownloadStatus status) {
Intent service = new Intent(mContext, DownloadService.class);
Intent service = new Intent(mContext, NDownloadService.class);
service.putExtra(DownloadConfig.KEY_DOWNLOAD_ENTRY, entry);
service.putExtra(DownloadConfig.KEY_DOWNLOAD_ACTION, status.name());
return service;
@ -562,6 +577,16 @@ public class DownloadManager implements DownloadStatusListener {
return mDownloadDao.getAllSnapshots();
}
/**
* 获取快照
*
* @param url 下载地址
*/
@Nullable
public DownloadEntity getDownloadEntitySnapshot(String url) {
return mDownloadDao.getSnapshot(url);
}
/**
* 获取快照
*
@ -802,6 +827,8 @@ public class DownloadManager implements DownloadStatusListener {
DownloadEntity entry = mDownloadDao.getSnapshot(url);
if (entry != null) {
AppExecutor.getIoExecutor().execute(() -> {
NDownloadBridge.INSTANCE.cancel(url);
mDownloadDao.delete(url);
if (isDeleteFile) {
@ -835,19 +862,16 @@ public class DownloadManager implements DownloadStatusListener {
private void cancelAndNotify(DownloadEntity entry, boolean cancelSilently) {
mDownloadDao.removeErrorMessage(entry.getUrl());
DownloadTask task = DataChanger.INSTANCE.getDownloadingTasks().get(entry.getUrl());
DownloadTask task = NDataChanger.INSTANCE.getDownloadingTasks().get(entry.getUrl());
if (task != null) {
task.cancel();
// 改任务队列的状态
DataChanger.INSTANCE.getDownloadingTasks().remove(entry.getUrl());
if (!cancelSilently) {
DataChanger.INSTANCE.notifyDataChanged(entry);
}
NDataChanger.INSTANCE.getDownloadingTasks().remove(entry.getUrl());
}
DataChanger.INSTANCE.getDownloadEntries().remove(entry.getUrl());
NDataChanger.INSTANCE.getDownloadEntries().remove(entry.getUrl());
if (!cancelSilently) {
DataChanger.INSTANCE.notifyDataChanged(entry);
DownloadStatusManager.getInstance().onTaskCancelled(entry);
NDataChanger.INSTANCE.notifyDataChanged(entry);
onTaskCancelled(entry);
}
Utils.log(DownloadManager.class.getSimpleName(), "cancel");
@ -857,7 +881,7 @@ public class DownloadManager implements DownloadStatusListener {
* 暂停所有正在下载的任务
*/
public void pauseAll() {
for (DownloadEntity entity : DataChanger.INSTANCE.getDownloadEntries().values()) {
for (DownloadEntity entity : NDataChanger.INSTANCE.getDownloadEntries().values()) {
pause(entity.getUrl());
}
Utils.log(DownloadManager.class.getSimpleName(), "pause all");
@ -868,7 +892,7 @@ public class DownloadManager implements DownloadStatusListener {
*/
public void pause(String url) {
checkDownloadEntryRecordValidate(url);
DownloadEntity entry = DataChanger.INSTANCE.getDownloadEntries().get(url);
DownloadEntity entry = NDataChanger.INSTANCE.getDownloadEntries().get(url);
if (entry != null) {
startDownloadService(entry, DownloadStatus.pause);
put(url, System.currentTimeMillis());
@ -884,14 +908,14 @@ public class DownloadManager implements DownloadStatusListener {
* 3.检查是否显示下载通知栏
*/
public void initDownloadService() {
final List<String> urlList = new ArrayList<>(DataChanger.INSTANCE.getDownloadingTasks().keySet());
final List<String> urlList = new ArrayList<>(NDataChanger.INSTANCE.getDownloadingTasks().keySet());
for (DownloadEntity downloadEntity : getAllDownloadEntity()) {
if (!urlList.contains(downloadEntity.getUrl()) &&
(downloadEntity.getStatus().equals(DownloadStatus.downloading)
|| downloadEntity.getStatus().equals(DownloadStatus.waiting))) {
downloadEntity.setStatus(DownloadStatus.subscribe);
mDownloadDao.newOrUpdate(downloadEntity);
DataChanger.INSTANCE.notifyDataChanged(downloadEntity);
NDataChanger.INSTANCE.notifyDataChanged(downloadEntity);
}
}
@ -904,7 +928,7 @@ public class DownloadManager implements DownloadStatusListener {
*/
public void addObserver(DataWatcher dataWatcher) {
Utils.log(DownloadManager.class.getSimpleName(), "addObserver");
DataChanger.INSTANCE.addObserver(dataWatcher);
NDataChanger.INSTANCE.addObserver(dataWatcher);
notifyDownloadStatusASAP(dataWatcher);
}
@ -914,7 +938,7 @@ public class DownloadManager implements DownloadStatusListener {
*/
public void removeObserver(DataWatcher dataWatcher) {
Utils.log(DownloadManager.class.getSimpleName(), "removeObserver");
DataChanger.INSTANCE.deleteObserver(dataWatcher);
NDataChanger.INSTANCE.deleteObserver(dataWatcher);
}
/**
@ -930,11 +954,11 @@ public class DownloadManager implements DownloadStatusListener {
* 初始化下载服务
*/
public void startDownloadService() {
Intent serviceIntent = new Intent(mContext, DownloadService.class);
Intent serviceIntent = new Intent(mContext, NDownloadService.class);
// 当满足系统版本大于 8.0 并且应用在后台运行时以前台服务开启
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
&& !PackageUtils.isAppOnForeground(mContext)) {
serviceIntent.putExtra(DownloadService.KEY_SERVICE_ACTION, DownloadService.START_FOREGROUND);
serviceIntent.putExtra(NDownloadService.KEY_SERVICE_ACTION, NDownloadService.START_FOREGROUND);
mContext.startForegroundService(serviceIntent);
} else {
/*
@ -974,7 +998,7 @@ public class DownloadManager implements DownloadStatusListener {
// 当满足系统版本大于 8.0 并且应用在后台运行时以前台服务开启
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
&& !PackageUtils.isAppOnForeground(mContext)) {
serviceIntent.putExtra(DownloadService.KEY_SERVICE_ACTION, DownloadService.START_FOREGROUND);
serviceIntent.putExtra(NDownloadService.KEY_SERVICE_ACTION, NDownloadService.START_FOREGROUND);
mContext.startForegroundService(serviceIntent);
} else {
mContext.startService(serviceIntent);
@ -1105,7 +1129,7 @@ public class DownloadManager implements DownloadStatusListener {
String mark = downloadEntity.getMeta().get(DOWNLOADED_IS_READ_MARK);
if (TextUtils.isEmpty(mark)) {
downloadEntity.getMeta().put(DOWNLOADED_IS_READ_MARK, DOWNLOADED_IS_READ_MARK);
mDownloadDao.newOrUpdate(downloadEntity);
mDownloadDao.update(downloadEntity, false);
if (!markHasChanged) markHasChanged = true;
}
}
@ -1145,12 +1169,12 @@ public class DownloadManager implements DownloadStatusListener {
String mark = downloadEntity.getMeta().get(DOWNLOADING_IS_READ_MARK);
if (TextUtils.isEmpty(mark)) {
downloadEntity.getMeta().put(DOWNLOADING_IS_READ_MARK, DOWNLOADING_IS_READ_MARK);
mDownloadDao.newOrUpdate(downloadEntity);
mDownloadDao.update(downloadEntity, false);
if (!markHasChanged) markHasChanged = true;
}
} else {
downloadEntity.getMeta().put(DOWNLOADING_IS_READ_MARK, "");
mDownloadDao.newOrUpdate(downloadEntity);
mDownloadDao.update(downloadEntity, false);
if (!markHasChanged) markHasChanged = true;
}
}
@ -1208,7 +1232,7 @@ public class DownloadManager implements DownloadStatusListener {
* 更新数据库中的下载实体
*/
public void updateDownloadEntity(DownloadEntity downloadEntity) {
mDownloadDao.newOrUpdate(downloadEntity);
mDownloadDao.update(downloadEntity, false);
}
/**
@ -1270,7 +1294,8 @@ public class DownloadManager implements DownloadStatusListener {
*/
public static void updateDownloadMetaMap() {
String isOverwrite;
if (LunchType.UPDATE.name().equals(SPUtils.getString(Constants.SP_INSTALL_TYPE))) {
String installType = SPUtils.getString(Constants.SP_INSTALL_TYPE);
if (LunchType.UPDATE.name().equals(installType)) {
isOverwrite = "true";
} else {
isOverwrite = "false";
@ -1285,6 +1310,7 @@ public class DownloadManager implements DownloadStatusListener {
map.put(HttpDnsManager.IMEI, MetaUtil.getBase64EncodedIMEI());
map.put(HttpDnsManager.TOKEN, UserManager.getInstance().getToken());
map.put(HttpDnsManager.IS_OVERWRITE, isOverwrite);
map.put(HttpDnsManager.INSTALL_TYPE, installType);
HttpDnsManager.metaMap = map;
}

View File

@ -32,13 +32,15 @@ import okhttp3.MediaType
import okhttp3.RequestBody
import org.json.JSONException
import org.json.JSONObject
import java.util.*
import java.util.concurrent.CopyOnWriteArrayList
object PackageObserver {
private val mPackageViewModel: PackageViewModel
by lazy { PackageViewModel(HaloApp.getInstance().application, PackageRepository) }
private val mPackageChangeListenerList: ArrayList<PackageChangeListener> = arrayListOf()
private val mPackageChangeListenerList = CopyOnWriteArrayList<PackageChangeListener>()
fun registerPackageChangeChangeListener(listener: PackageChangeListener) {
mPackageChangeListenerList.add(listener)

View File

@ -83,7 +83,7 @@ class DownloadDialogAdapter(
holder.binding.root.layoutParams = this
}
val section = listData[position].section
holder.binding.title.text = if (section == DownloadDialogSectionType.OTHER) "其它版本" else "我的版本"
holder.binding.title.text = if (section == DownloadDialogSectionType.OTHER) "更多版本" else "我的版本"
holder.binding.otherVersionHint.goneIf(section != DownloadDialogSectionType.OTHER)
}
is DownloadDialogLinkItemViewHolder -> {

View File

@ -83,10 +83,6 @@ object DownloadMessageHandler : InnerDownloadListener {
}
}
override fun onDownloadComplete(id: String?, elapsedTime: Long) {
// do nothing
}
/**
* 重定向中的回调
* @param id 下载 id
@ -218,6 +214,10 @@ object DownloadMessageHandler : InnerDownloadListener {
// do nothing
}
override fun onDownloadComplete(id: String?, elapsedTime: Long) {
// do nothing
}
fun registerListener(id: String, listener: DownloadListener) {
var listenerList = mListenerMap[id]
if (listenerList == null) {

View File

@ -38,21 +38,21 @@ import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
import com.facebook.drawee.backends.pipeline.Fresco
import com.facebook.imagepipeline.core.ImagePipeline
import com.facebook.imagepipeline.request.ImageRequest
import com.gh.gamecenter.common.base.activity.BaseActivity
import com.gh.common.constant.Config
import com.gh.gamecenter.core.runOnIoThread
import com.gh.gamecenter.common.base.activity.BaseActivity
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.entity.CommunityEntity
import com.gh.gamecenter.common.retrofit.Response
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.utils.ImageUtils.getTransformedUrl
import com.gh.gamecenter.common.view.DraggableBigImageView
import com.gh.gamecenter.common.view.Gh_RelativeLayout
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.runOnIoThread
import com.gh.gamecenter.core.utils.*
import com.gh.gamecenter.databinding.ActivityViewimageBinding
import com.gh.gamecenter.common.entity.CommunityEntity
import com.gh.gamecenter.entity.ImageInfoEntity
import com.gh.gamecenter.qa.article.detail.ArticleDetailActivity
import com.gh.gamecenter.feature.entity.AnswerEntity
import com.gh.gamecenter.common.retrofit.Response
import com.gh.gamecenter.qa.article.detail.ArticleDetailActivity
import com.gh.gamecenter.retrofit.RetrofitManager
import com.github.piasy.biv.view.BigImageView
import com.github.piasy.biv.view.FrescoImageViewFactory
@ -849,9 +849,9 @@ class ImageViewerActivity : BaseActivity(), OnPageChangeListener {
// ssiv.resetScaleAndCenter()
// }
// })
ssiv.setOnClickListener {
onBackPressed()
}
}
imageView.setOnClickListener {
onBackPressed()
}
}
})

View File

@ -36,10 +36,10 @@ import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.appcompat.content.res.AppCompatResources;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.fragment.app.Fragment;
import androidx.lifecycle.ViewModelProviders;
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat;
import com.facebook.drawee.view.SimpleDraweeView;
import com.gh.common.DefaultUrlHandler;
@ -307,15 +307,15 @@ public class MainActivity extends BaseActivity {
checkDialog();
}
// 默认配置为空时重试
if (Config.getSettings() == null) {
Config.getGhzsSettings();
}
// 耗时操作
AppExecutor.getIoExecutor().execute(() -> {
// 上传数据
DataCollectionManager.getInstance().upload();
// 获取默认配置
if (Config.getSettings() == null) {
Config.getGhzsSettings();
}
// 初始化PlatformUtils
PlatformUtils.getInstance(getApplicationContext());
@ -507,7 +507,27 @@ public class MainActivity extends BaseActivity {
private void observeStartUpAd() {
final StartupAdEntity startUpAd = AdHelper.getStartUpAd();
if (startUpAd != null && !TextUtils.isEmpty(startUpAd.getImg())) {
// 根据接口返回的广告时间,判断该图片广告是否还有必要显示
boolean isAdValid = false;
if (startUpAd.getTime() != null) {
long currentTimeInSecond = System.currentTimeMillis() / 1000;
if (currentTimeInSecond > startUpAd.getTime().getStart()
&& currentTimeInSecond < startUpAd.getTime().getEnd()) {
isAdValid = true;
}
} else {
// 接口没有返回开始和结束时间时,默认有效
isAdValid = true;
}
// 图片广告无效,跳过
if (!isAdValid) {
hideStartUpAd();
return;
}
final String showedTodayTimestamp = SPUtils.getString(Constants.SP_STARTUP_AD_TIMESTAMP, "");
final String rule = startUpAd.getRule();
switch (rule) {
@ -594,7 +614,7 @@ public class MainActivity extends BaseActivity {
SimpleDraweeView adImage = findViewById(R.id.adImage);
startAdContainer.setVisibility(View.VISIBLE);
jumpDetailBtn.setText(ad.getDesc());
ExtensionsKt.setDrawableEnd(jumpDetailBtn, VectorDrawableCompat.create(getResources(), R.drawable.ic_startup_ad_arrow, null), null, null);
ExtensionsKt.setDrawableEnd(jumpDetailBtn, AppCompatResources.getDrawable(this, R.drawable.ic_startup_ad_arrow), null, null);
ImageUtils.display(adImage, ad.getImg());
startAdContainer.setOnClickListener(v -> {
// do nothing 只是为了点击拦截事件,避免传递到下面的页面
@ -987,7 +1007,7 @@ public class MainActivity extends BaseActivity {
public void onEventMainThread(EBNetworkState busNetworkState) {
if (busNetworkState.isNetworkConnected()) {
if (Config.getSettings() == null) {
AppExecutor.getIoExecutor().execute(Config::getGhzsSettings);
Config.getGhzsSettings();
}
mPackageViewModel.checkData();

View File

@ -107,6 +107,12 @@ open class SearchActivity : BaseActivity() {
) {
updateDisplayType(DEFAULT)
}
SensorsBridge.trackEvent(
"SearchPageShow",
"source_entrance",
intent.getStringExtra(EntranceConsts.KEY_SOURCE_ENTRANCE) ?: ""
)
}
open fun initSearchBar() {
@ -172,6 +178,7 @@ open class SearchActivity : BaseActivity() {
mSearchKey = key
updateDisplayType(GAME_DIGEST)
LogUtils.uploadSearchGame("searching", "搜索页", key, "自动搜索")
SensorsBridge.trackEvent("SearchButtonClick", "search_content", key ?: "", "search_type", "输入搜索")
}
}
@ -181,6 +188,7 @@ open class SearchActivity : BaseActivity() {
searchEt.setSelection(searchEt.text.length)
updateDisplayType(GAME_DETAIL)
LogUtils.uploadSearchGame("searching", "搜索页", key, "默认搜索")
SensorsBridge.trackEvent("SearchButtonClick", "search_content", key ?: "", "search_type", "默认搜索")
// MtaHelper.onEvent("游戏搜索", "默认搜索", key)
}
@ -197,6 +205,7 @@ open class SearchActivity : BaseActivity() {
searchEt.setSelection(searchEt.text.length)
updateDisplayType(GAME_DETAIL)
LogUtils.uploadSearchGame("searching", "搜索页", key, "历史搜索")
SensorsBridge.trackEvent("SearchButtonClick", "search_content", key ?: "", "search_type", "历史搜索")
// MtaHelper.onEvent("游戏搜索", "历史搜索", key)
}
@ -211,6 +220,7 @@ open class SearchActivity : BaseActivity() {
} else if (newSearchKey != mSearchKey || mDisplayType != GAME_DETAIL) {
mSearchKey = newSearchKey
if (!TextUtils.isEmpty(mSearchKey)) {
SensorsBridge.trackEvent("SearchButtonClick", "search_content", newSearchKey, "search_type", "输入搜索")
mDao?.add(mSearchKey)
updateDisplayType(GAME_DETAIL)
} else {
@ -293,11 +303,18 @@ open class SearchActivity : BaseActivity() {
private const val HINT_TEXT = "搜索游戏..."
@JvmStatic
fun getIntent(context: Context, searchImmediately: Boolean, hint: String, entrance: String): Intent {
fun getIntent(
context: Context,
searchImmediately: Boolean,
hint: String,
entrance: String,
sourceEntrance: String
): Intent {
val intent = Intent(context, SearchActivity::class.java)
intent.putExtra(KEY_SEARCH_IMMEDIATELY, searchImmediately)
intent.putExtra(EntranceConsts.KEY_HINT, hint)
intent.putExtra(EntranceConsts.KEY_ENTRANCE, entrance)
intent.putExtra(EntranceConsts.KEY_SOURCE_ENTRANCE, sourceEntrance)
return intent
}
}

View File

@ -17,8 +17,8 @@ import androidx.core.app.ActivityCompat
import androidx.viewpager.widget.PagerAdapter
import androidx.viewpager.widget.ViewPager
import com.alibaba.android.arouter.facade.annotation.Route
import com.alibaba.android.arouter.launcher.ARouter
import com.g00fy2.versioncompare.Version
import com.gh.common.constant.Config
import com.gh.common.dialog.NewPrivacyPolicyDialogFragment
import com.gh.common.util.*
import com.gh.common.util.DialogUtils
@ -31,13 +31,17 @@ import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.common.tracker.TrackerLogger
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.provider.IAppProvider
import com.gh.gamecenter.core.provider.IPackageUtilsProvider
import com.gh.gamecenter.core.runOnIoThread
import com.gh.gamecenter.core.utils.*
import com.gh.gamecenter.entity.PrivacyPolicyEntity
import com.gh.gamecenter.feature.utils.PlatformUtils
import com.gh.gamecenter.pkg.PkgHelper
import com.gh.vspace.VHelper
import com.halo.assistant.HaloApp
import com.lightgame.download.FileUtils
import org.json.JSONObject
import pub.devrel.easypermissions.AfterPermissionGranted
import pub.devrel.easypermissions.EasyPermissions
import java.io.BufferedReader
@ -149,6 +153,28 @@ class SplashScreenActivity : BaseActivity() {
}
}
private fun logAppLaunch() {
val packageUtilsConfig =
ARouter.getInstance().build(RouteConsts.provider.packageUtils).navigation() as? IPackageUtilsProvider
val appProvider = ARouter.getInstance().build(RouteConsts.provider.app).navigation() as? IAppProvider
val signatureHash = packageUtilsConfig?.getApkSignatureByPackageName(this, packageName)?.get(0)
val sideLoadInfo = packageUtilsConfig?.getSideLoadedInfo()
val trackEvent = JSONObject()
tryCatchInRelease {
trackEvent.run {
put("\$is_first_time", SPUtils.getBoolean(Constants.SP_SENSORS_IS_FIRST_TIME, true))
put("is_side_loaded", sideLoadInfo?.get("is_side_loaded").toBoolean())
put("installer_store", sideLoadInfo?.get("installer_store") ?: "")
put("package_name", packageName)
put("signature", signatureHash)
put("app_name", appProvider?.getAppName())
put("install_first_time", if (HaloApp.getInstance().isBrandNewInstall) "" else "")
}
}
SensorsBridge.trackEvent("AppLaunch", trackEvent)
SPUtils.setBoolean(Constants.SP_SENSORS_IS_FIRST_TIME, false)
}
private fun showPrivacyDialog(guideLayout: ViewPager) {
NewPrivacyPolicyDialogFragment.show(this, null) { isSuccess: Boolean ->
if (isSuccess) {
@ -268,11 +294,17 @@ class SplashScreenActivity : BaseActivity() {
overridePendingTransition(0, 0)
startActivity(intent)
doFlavorInit()
logAppLaunch()
finish()
}
private fun doFlavorInit() {
HaloApp.getInstance().flavorProvider.init(HaloApp.getInstance(), this)
// 仅官网渠道和测试包启用神策
if ("GH_206" == HaloApp.getInstance().channel || PackageFlavorHelper.IS_TEST_FLAVOR) {
SensorsBridge.init(HaloApp.getInstance(), HaloApp.getInstance().channel)
}
}
private fun getGitLogString(): String {
@ -347,7 +379,6 @@ class SplashScreenActivity : BaseActivity() {
private fun prefetchData() {
runOnIoThread {
Config.getGhzsSettings()
mViewModel?.deviceDialogSetting()
mViewModel?.filterDetailTags()
mViewModel?.authDialog()
@ -356,6 +387,10 @@ class SplashScreenActivity : BaseActivity() {
checkAndPostUsageStats()
updateGameSubstituteRepository()
if (BuildConfig.CONFIG_ID.isNotEmpty()) {
PkgHelper.requestPkgConfig(BuildConfig.CONFIG_ID)
}
// 获取自动刷新的cd获取版本对应表
val time = mSharedPreferences!!.getString("refresh_time", null)
val format = SimpleDateFormat("yyyy-MM-dd", Locale.getDefault())
@ -438,7 +473,7 @@ class SplashScreenActivity : BaseActivity() {
if (position == mPics.size - 1) {
val tvSkip = view.findViewById<TextView>(R.id.splsh_guide_tv_skip)
// 如果屏幕特短,或者是平板的横屏显示,把图片改成按高度显示
if (DisplayUtils.isUltraShortScreen()) {
if (DisplayUtils.isUltraShortScreen(this@SplashScreenActivity)) {
ivImage.scaleType = ImageView.ScaleType.CENTER_INSIDE
}
tvSkip.setOnClickListener {

View File

@ -21,6 +21,7 @@ import androidx.annotation.NonNull;
import com.alibaba.android.arouter.facade.annotation.Route;
import com.gh.common.constant.Config;
import com.gh.gamecenter.common.utils.SensorsBridge;
import com.gh.gamecenter.energy.EnergyBridge;
import com.gh.common.util.IntegralLogHelper;
import com.gh.gamecenter.common.callback.BiCallback;
@ -275,6 +276,12 @@ public class WeiBoShareActivity extends Activity implements WbShareCallback {
ShareUtils.resourceId,
"新浪微博"
);
SensorsBridge.trackEvent(
"GameCollectDetailShareClickSuccess",
"game_collect_title", ShareUtils.shareEntity.getShareTitle(),
"game_collect_id", ShareUtils.resourceId,
"share_type", "新浪微博"
);
}
} else {
IntegralLogHelper.INSTANCE.logInviteResult("成功", "微博");

View File

@ -1,5 +1,6 @@
package com.gh.gamecenter.adapter;
import android.content.ActivityNotFoundException;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
@ -23,6 +24,7 @@ import com.gh.common.util.PackageUtils;
import com.gh.gamecenter.core.utils.TimeUtils;
import com.gh.gamecenter.R;
import com.gh.gamecenter.adapter.viewholder.KcSelectGameViewHolder;
import com.gh.gamecenter.core.utils.ToastUtils;
import com.gh.gamecenter.databinding.KcGameSelectItemBinding;
import com.gh.gamecenter.feature.entity.InstallGameEntity;
import com.gh.gamecenter.common.retrofit.Response;
@ -284,7 +286,11 @@ public class CleanApkAdapter extends BaseRecyclerAdapter<KcSelectGameViewHolder>
singleChoose(position);
} else {
if (mIsScanOver) {
mContext.startActivity(PackageInstaller.getInstallIntent(mContext, gameEntity.getGamePath()));
try {
mContext.startActivity(PackageInstaller.getInstallIntent(mContext, gameEntity.getGamePath()));
} catch (ActivityNotFoundException e) {
ToastUtils.toast("找不到 APK 安装器,请稍后再试");
}
}
}
});

View File

@ -202,7 +202,7 @@ public class LibaoDetailAdapter extends BaseRecyclerAdapter<ViewHolder> {
if (mLibaoEntity.getGame() != null) {
holder.binding.libaodetailGameIcon.displayGameIcon(mLibaoEntity.getGame().getIcon(), mLibaoEntity.getGame().getIconSubscript(), mLibaoEntity.getGame().getIconFloat());
GameEntity gameEntity = mLibaoEntity.getGame().toGameEntity();
GameItemViewHolder.initGameSubtitle(gameEntity, holder.binding.gameSubtitleTv, null, null, false, null);
GameItemViewHolder.initGameSubtitleAndAdLabel(gameEntity, holder.binding.gameSubtitleTv, null, null, false, null, false, null);
} else {
holder.binding.libaodetailGameIcon.displayGameIcon(mLibaoEntity.getIcon(), null, mLibaoEntity.getGame().getIconFloat());
}
@ -245,7 +245,7 @@ public class LibaoDetailAdapter extends BaseRecyclerAdapter<ViewHolder> {
List<UserDataLibaoEntity> userDataLibaoList = mLibaoEntity.getMe().getUserDataLibaoList();
LibaoUtils.initLibaoBtn(mContext, holder.binding.libaodetailCopyBtn, mLibaoEntity,
mLibaoDetailEntity.getInstallRequired(), this, false,
StringUtils.buildString(mEntrance, "+(礼包详情[", mLibaoEntity.getName(), "])"), null);
StringUtils.buildString(mEntrance, "+(礼包详情[", mLibaoEntity.getName(), "])"), "礼包详情", null);
if (mLibaoEntity.getUniversal()) {
holder.binding.libaodetailDes.setVisibility(View.GONE);
} else {
@ -285,7 +285,7 @@ public class LibaoDetailAdapter extends BaseRecyclerAdapter<ViewHolder> {
if (mLibaoEntity.getStatus() != null && mLibaoDetailEntity != null) {
LibaoUtils.initLibaoBtn(mContext, holder.binding.libaodetailCopyBtn, mLibaoEntity,
mLibaoDetailEntity.getInstallRequired(), this, false,
StringUtils.buildString(mEntrance, "+(礼包详情[", mLibaoEntity.getName(), "])"), null);
StringUtils.buildString(mEntrance, "+(礼包详情[", mLibaoEntity.getName(), "])"), "礼包详情", null);
}
// 判断按钮状态是否为空(礼包详情进入),重新获取

View File

@ -12,6 +12,7 @@ import androidx.fragment.app.DialogFragment;
import androidx.fragment.app.FragmentActivity;
import com.airbnb.lottie.LottieAnimationView;
import com.gh.gamecenter.common.base.GlobalActivityManager;
import com.gh.common.chain.BrowserInstallHandler;
import com.gh.common.chain.CertificationHandler;
import com.gh.common.chain.ChainBuilder;
@ -28,6 +29,7 @@ import com.gh.common.chain.VersionNumberHandler;
import com.gh.common.constant.Config;
import com.gh.common.dialog.DeviceRemindDialog;
import com.gh.common.dialog.GameOffServiceDialogFragment;
import com.gh.gamecenter.common.utils.SensorsBridge;
import com.gh.gamecenter.feature.exposure.ExposureEvent;
import com.gh.common.filter.RegionSetting;
import com.gh.common.filter.RegionSettingHelper;
@ -157,6 +159,23 @@ public class DetailViewHolder {
@Override
public void onClick(View v) {
if (mViewHolder.mDownloadPb.getButtonStyle() != DownloadButton.ButtonStyle.RESERVABLE && mViewHolder.mDownloadPb.getButtonStyle() != DownloadButton.ButtonStyle.RESERVED) {
SensorsBridge.trackEvent(
"DownLoadbuttonClick",
"game_id", mGameEntity.getId(),
"game_name", mGameEntity.getName(),
"game_type", mGameEntity.getCategoryChinese(),
"download_status", mGameEntity.getDownloadStatusChinese(),
"button_name", mViewHolder.mDownloadPb.getText(),
"page_name", GlobalActivityManager.getCurrentPageEntity().getPageName(),
"page_id", GlobalActivityManager.getCurrentPageEntity().getPageId(),
"page_business_id", GlobalActivityManager.getCurrentPageEntity().getPageBusinessId(),
"last_page_name", GlobalActivityManager.getLastPageEntity().getPageName(),
"last_page_id", GlobalActivityManager.getLastPageEntity().getPageId(),
"last_page_business_id", GlobalActivityManager.getLastPageEntity().getPageBusinessId()
);
}
// 这个 switch 纯粹是为了 MTA和上报光能任务 统计用的
switch (mViewHolder.mDownloadPb.getButtonStyle()) {
case DOWNLOADING_PLUGIN:
@ -393,8 +412,9 @@ public class DetailViewHolder {
break;
case RESERVABLE:
GamePermissionDialogFragment.show((AppCompatActivity) mViewHolder.context, mGameEntity, mGameEntity.getInfo(), () -> {
SensorsBridge.trackEvent("AppointmentGame", "game_name", mGameEntity.getName(), "game_id", mGameEntity.getId());
CheckLoginUtils.checkLogin(mViewHolder.context, mEntrance, () -> {
ReservationHelper.reserve(mViewHolder.context, mGameEntity.getId(), () -> {
ReservationHelper.reserve(mViewHolder.context, mGameEntity.getId(), mGameEntity.getName(), () -> {
LogUtils.logReservation(mGameEntity, mTraceEvent);
DetailDownloadUtils.detailInitDownload(mViewHolder, false);
});

View File

@ -12,7 +12,6 @@ import com.facebook.drawee.view.SimpleDraweeView;
import com.gh.gamecenter.R;
import com.gh.gamecenter.common.utils.ExtensionsKt;
import com.gh.gamecenter.common.view.DrawableView;
import com.gh.gamecenter.common.view.NoEllipsizeSpaceTextView;
import com.gh.gamecenter.feature.databinding.GameItemBinding;
import com.gh.gamecenter.feature.entity.ColorEntity;
import com.gh.gamecenter.feature.entity.GameEntity;
@ -22,7 +21,7 @@ import com.gh.gamecenter.feature.view.GameIconView;
public class GameViewHolder extends RecyclerView.ViewHolder {
public GameIconView gameThumb;
public NoEllipsizeSpaceTextView gameName;
public TextView gameName;
public DownloadButton gameDownloadBtn;
public TextView gameDes;
public LinearLayout gameLabelList;

View File

@ -27,8 +27,8 @@ import com.gh.gamecenter.databinding.AmwayCommentItemBinding
import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.feature.exposure.ExposureSource
import com.gh.gamecenter.game.GameAndPosition
import com.gh.gamecenter.feature.game.GameItemViewHolder
import com.gh.gamecenter.game.GameAndPosition
import com.gh.gamecenter.game.vertical.GameVerticalAdapter
import com.gh.gamecenter.gamedetail.rating.RatingFragment
import com.gh.gamecenter.gamedetail.rating.RatingReplyActivity
@ -240,7 +240,7 @@ class AmwayAdapter(
}
itemData.exposureEvent = ExposureEvent.createEvent(gameEntity, basicExposureSource)
GameItemViewHolder.initGameSubtitle(gameEntity, binding.gameSubtitleTv)
GameItemViewHolder.initGameSubtitleAndAdLabel(gameEntity, binding.gameSubtitleTv)
binding.gameContainer.setOnClickListener {
GameDetailActivity.startGameDetailActivity(

View File

@ -256,11 +256,6 @@ class AmwayFragment : LazyListFragment<AmwayListItemData, AmwayViewModel>() {
MtaHelper.onEventWithTime("安利墙", mElapsedHelper.elapsedTime, "浏览")
}
override fun onResume() {
if (isEverPause) mAdapter?.notifyDataSetChanged()
super.onResume()
}
override fun onFragmentResume() {
super.onFragmentResume()
DownloadManager.getInstance().addObserver(dataWatcher)

View File

@ -2,8 +2,8 @@ package com.gh.gamecenter.amway.search
import android.os.Bundle
import android.view.View
import androidx.appcompat.content.res.AppCompatResources
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat
import com.gh.gamecenter.R
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.databinding.FragmentAmwaySearchDefaultBinding
@ -65,11 +65,12 @@ class AmwaySearchDefaultFragment : SearchDefaultFragment() {
headTitle.textSize = 16F
headActionTv.text = "清空"
headActionTv.setTextColor(R.color.text_subtitleDesc.toColor(requireContext()))
headActionTv.setDrawableStart(VectorDrawableCompat.create(
resources,
R.drawable.search_history_delete,
null
))
headActionTv.setDrawableStart(
AppCompatResources.getDrawable(
requireContext(),
R.drawable.search_history_delete
)
)
headActionTv.setOnClickListener {
DialogHelper.showCenterWarningDialog(requireContext(), "清空记录", "确定清空历史搜索记录?", confirmClickCallback = {
mSearchDao.deleteAll()

View File

@ -154,7 +154,6 @@ class NewCatalogListFragment : ListFragment<GameEntity, NewCatalogListViewModel>
}
override fun onResume() {
if (isEverPause && mAdapter != null) mAdapter?.notifyDataSetChanged()
super.onResume()
DownloadManager.getInstance().addObserver(mDataWatcher)
}

View File

@ -103,7 +103,6 @@ class NewCategoryListFragment : ListFragment<GameEntity, NewCategoryListViewMode
}
override fun onResume() {
if (isEverPause && mAdapter != null) mAdapter?.notifyDataSetChanged()
super.onResume()
DownloadManager.getInstance().addObserver(mDataWatcher)
}

View File

@ -179,6 +179,7 @@ class CategoryV2Fragment : LazyFragment() {
}
private fun showGuide() {
if (!isAdded) return
mBinding?.run {
val isShow = SPUtils.getBoolean(Constants.SP_SHOW_CATEGORY_GUIDE)
if (isShow) return
@ -206,6 +207,7 @@ class CategoryV2Fragment : LazyFragment() {
requireContext(),
false,
"",
"新分类2.0",
"新分类2.0"
)
startActivity(intent)

View File

@ -27,6 +27,8 @@ import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.gh.gamecenter.feature.game.GameItemViewHolder
import com.lightgame.download.DownloadEntity
import org.json.JSONException
import org.json.JSONObject
class CategoryV2ListAdapter(
context: Context,
@ -168,7 +170,21 @@ class CategoryV2ListAdapter(
),
StringUtils.buildString(selectedSubCatalogName, ":", gameEntity.name),
event
)
) {
val trackEvent = JSONObject()
try {
trackEvent.put("navigation_bar_name", mCategoryViewModel.selectedCategoryName)
trackEvent.put("game_tag", mCategoryViewModel.selectedCategoryList.map { it.name })
trackEvent.put("game_status", gameEntity.category)
trackEvent.put(
"inclusion_size",
if (gameEntity.getApk().size == 1) gameEntity.getApk()[0].size ?: "" else ""
)
} catch (e: JSONException) {
e.printStackTrace()
}
SensorsBridge.trackEvent("ClassificationFilterCriteriaSelected", trackEvent)
}
DownloadItemUtils.updateItem(
mContext,
@ -221,7 +237,6 @@ class CategoryV2ListAdapter(
inner class CategoryGameItemViewHolder(val binding: CategoryGameItemBinding) :
BaseRecyclerViewHolder<Any>(binding.root) {
fun bindGameItem(gameEntity: GameEntity) {
binding.run {
gameIconView.displayGameIcon(gameEntity)
@ -240,7 +255,7 @@ class CategoryV2ListAdapter(
)
gameDes.text = gameEntity.decoratedDes
GameItemViewHolder.initGameSubtitle(gameEntity, gameSubtitleTv, gameDesSpace, root)
GameItemViewHolder.initGameSubtitleAndAdLabel(gameEntity, gameSubtitleTv)
}
}
@ -279,6 +294,8 @@ class CategoryV2ListAdapter(
recommendContainer = binding.recommendContainer
recommendTv = binding.recommendTv
recommendIv = binding.recommendIv
multiVersionDownloadTv = binding.multiVersionDownloadTv
gameDownloadTips = binding.downloadTipsLottie
}
}
}

View File

@ -283,7 +283,6 @@ class CategoryV2ListFragment : ListFragment<GameEntity, CategoryV2ListViewModel>
}
override fun onResume() {
if (isEverPause && mAdapter != null) mAdapter?.notifyDataSetChanged()
super.onResume()
DownloadManager.getInstance().addObserver(mDataWatcher)
}

View File

@ -80,6 +80,12 @@ class CloudArchiveManagerActivity : BaseActivity_TabLayout() {
setToolbarMenu(R.menu.menu_cloud_archive_manager)
updateStatusBarColor(R.color.background_white, R.color.background_white)
NewFlatLogUtils.logCloudArchiveManagePageShow(mGameEntity?.id ?: "", mGameEntity?.name ?: "", mEntrance)
SensorsBridge.trackEvent(
"CloudSaveManagePageShow",
"game_id", mGameEntity?.id ?: "",
"game_name", mGameEntity?.name ?: "",
"source_entrance", mEntrance
)
mBinding.run {
mGameEntity?.let {
@ -95,6 +101,11 @@ class CloudArchiveManagerActivity : BaseActivity_TabLayout() {
) -> toast("暂未检测到本地的存档数据,请玩会儿游戏再试~")
else -> {
NewFlatLogUtils.logCloudArchiveUploadDialogShow()
SensorsBridge.trackEvent(
"CloudSaveUploadDialogShow",
"game_id", mGameEntity?.id ?: "",
"game_name", mGameEntity?.name ?: ""
)
showUploadDialog()
}
}
@ -109,6 +120,11 @@ class CloudArchiveManagerActivity : BaseActivity_TabLayout() {
toast("上传失败")
}
}
mViewModel.gameEntityLiveData.observeNonNull(this) {
mGameEntity = it
initDownloadBtn()
}
}
override fun onMenuItemClick(item: MenuItem?): Boolean {
@ -145,6 +161,15 @@ class CloudArchiveManagerActivity : BaseActivity_TabLayout() {
mGameEntity?.name ?: "",
if (position == MY_ARCHIVE_INDEX) "我的存档" else if (position == MY_DOWNLOAD_ARCHIVE_INDEX) "我的下载" else "我的分享"
)
SensorsBridge.trackEvent(
"CloudSaveManagePageTabSelected",
"game_id",
mGameEntity?.id ?: "",
"game_name",
mGameEntity?.name ?: "",
"tab_name",
if (position == MY_ARCHIVE_INDEX) "我的存档" else if (position == MY_DOWNLOAD_ARCHIVE_INDEX) "我的下载" else "我的分享"
)
controlUploadGameArchive()
}
@ -191,6 +216,12 @@ class CloudArchiveManagerActivity : BaseActivity_TabLayout() {
}
confirmTv.setOnClickListener {
NewFlatLogUtils.logCloudArchiveUploadDialogClick("确定")
SensorsBridge.trackEvent(
"CloudSaveUploadDialogClick",
"game_id", mGameEntity?.id ?: "",
"game_name", mGameEntity?.name ?: "",
"button_name", "确定"
)
if (contentEt.text.trim().length in 3..30) {
saveAndUploadArchive(contentEt.text.toString().trim())
dialog.dismiss()
@ -200,6 +231,12 @@ class CloudArchiveManagerActivity : BaseActivity_TabLayout() {
}
cancelTv.setOnClickListener {
NewFlatLogUtils.logCloudArchiveUploadDialogClick("取消")
SensorsBridge.trackEvent(
"CloudSaveUploadDialogClick",
"game_id", mGameEntity?.id ?: "",
"game_name", mGameEntity?.name ?: "",
"button_name", "取消"
)
dialog.dismiss()
}
}

View File

@ -11,6 +11,8 @@ import com.gh.gamecenter.common.baselist.LoadType
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.common.utils.toRequestBody
import com.gh.gamecenter.entity.ArchiveEntity
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.utils.ApkActiveUtils
import com.gh.gamecenter.retrofit.RetrofitManager
import com.gh.vspace.VArchiveHelper
import com.halo.assistant.HaloApp
@ -31,12 +33,15 @@ class CloudArchiveManagerViewModel(
ListViewModel<ArchiveEntity, ArchiveEntity>(application) {
var archiveConfigStr = ""
private val mApi = RetrofitManager.getInstance().newApi
private val mNewApi = RetrofitManager.getInstance().newApi
private val mApi = RetrofitManager.getInstance().api
val uploadSuccess = MutableLiveData<Boolean>()
val shareSuccess = MutableLiveData<Boolean>()
val gameEntityLiveData = MutableLiveData<GameEntity>()
init {
getGameDigest()
if (configUrl.isNotEmpty()) getArchiveConfigString(configUrl)
}
@ -49,10 +54,10 @@ class CloudArchiveManagerViewModel(
override fun provideDataObservable(page: Int): Observable<List<ArchiveEntity>>? = when (mType) {
MyArchiveFragment.Type.MY_ARCHIVE -> {
mApi.getMyArchives(gameId, page)
mNewApi.getMyArchives(gameId, page)
}
MyArchiveFragment.Type.MY_DOWNLOAD_ARCHIVE -> null
MyArchiveFragment.Type.MY_SHARE_ARCHIVE -> mApi.getMyShareArchives(gameId, page)
MyArchiveFragment.Type.MY_SHARE_ARCHIVE -> mNewApi.getMyShareArchives(gameId, page)
}
override fun provideDataSingle(page: Int): Single<MutableList<ArchiveEntity>>? {
@ -86,6 +91,20 @@ class CloudArchiveManagerViewModel(
}
}
private fun getGameDigest() {
mApi.getGameDigest(gameId)
.map(ApkActiveUtils.filterMapper)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : com.gh.gamecenter.common.retrofit.Response<GameEntity>() {
override fun onResponse(response: GameEntity?) {
response?.let {
gameEntityLiveData.postValue(it)
}
}
})
}
@SuppressLint("CheckResult")
fun postArchive(archiveEntity: ArchiveEntity) {
val paramsMap = mapOf(
@ -95,7 +114,7 @@ class CloudArchiveManagerViewModel(
"game_version" to archiveEntity.gameVersion,
"md5" to archiveEntity.md5
)
mApi.postMyArchive(gameId, paramsMap.toRequestBody())
mNewApi.postMyArchive(gameId, paramsMap.toRequestBody())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : BiResponse<ResponseBody>() {
@ -117,7 +136,7 @@ class CloudArchiveManagerViewModel(
"share_desc" to shareDesc,
"is_shared" to true
)
mApi.patchMyArchive(gameId, archiveEntity.id, paramsMap.toRequestBody())
mNewApi.patchMyArchive(gameId, archiveEntity.id, paramsMap.toRequestBody())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : BiResponse<ResponseBody>() {
@ -141,7 +160,7 @@ class CloudArchiveManagerViewModel(
val paramsMap = mapOf(
"is_shared" to false
)
mApi.patchMyArchive(gameId, archiveEntity.id, paramsMap.toRequestBody())
mNewApi.patchMyArchive(gameId, archiveEntity.id, paramsMap.toRequestBody())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : BiResponse<ResponseBody>() {
@ -162,7 +181,7 @@ class CloudArchiveManagerViewModel(
val paramsMap = mapOf(
"name" to archiveEntity.name
)
mApi.patchMyArchive(gameId, archiveEntity.id, paramsMap.toRequestBody())
mNewApi.patchMyArchive(gameId, archiveEntity.id, paramsMap.toRequestBody())
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : BiResponse<ResponseBody>() {
@ -174,7 +193,7 @@ class CloudArchiveManagerViewModel(
@SuppressLint("CheckResult")
fun deleteArchive(archiveEntity: ArchiveEntity) {
mApi.deleteMyArchive(gameId, archiveEntity.id)
mNewApi.deleteMyArchive(gameId, archiveEntity.id)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : BiResponse<ResponseBody>() {

View File

@ -16,13 +16,14 @@ import com.gh.gamecenter.common.viewholder.FooterViewHolder
import com.gh.gamecenter.databinding.ItemMyArchiveBinding
import com.gh.gamecenter.databinding.ItemMyShareArchiveBinding
import com.gh.gamecenter.entity.ArchiveEntity
import com.gh.gamecenter.feature.entity.GameEntity
class MyArchiveAdapter(
context: Context,
private val mFragment: Fragment,
private val mViewModel: CloudArchiveManagerViewModel,
private val mType: MyArchiveFragment.Type,
private val mPackageName: String
private val mGameEntity: GameEntity?
) : ListAdapter<ArchiveEntity>(context) {
override fun getItemViewType(position: Int): Int {
@ -50,16 +51,23 @@ class MyArchiveAdapter(
timeTv.text = entity.time.update.formatTime("yyyy-MM-dd HH:mm")
versionTv.text = "版本:${entity.gameVersion}"
optionsIv.setOnClickListener {
MyArchiveOptionDialogFragment.show(mContext as AppCompatActivity, mViewModel, mType, entity)
MyArchiveOptionDialogFragment.show(
mContext as AppCompatActivity,
mViewModel,
mType,
entity,
mGameEntity
)
}
val entrance = if (mType == MyArchiveFragment.Type.MY_ARCHIVE) "云存档-我的存档" else "云存档-我的下载"
ArchiveDownloadButtonHelper.bindItem(
mContext,
entrance,
mFragment,
mPackageName,
mGameEntity?.getUniquePackageName() ?: "",
entity,
actionTv
actionTv,
mGameEntity
) {
if (mContext is CloudArchiveManagerActivity) {
(mContext as CloudArchiveManagerActivity).updateMyShareArchive()
@ -77,15 +85,22 @@ class MyArchiveAdapter(
versionTv.text = "版本:${entity.gameVersion}"
descTv.text = entity.desc
optionsIv.setOnClickListener {
MyArchiveOptionDialogFragment.show(mContext as AppCompatActivity, mViewModel, mType, entity)
MyArchiveOptionDialogFragment.show(
mContext as AppCompatActivity,
mViewModel,
mType,
entity,
mGameEntity
)
}
ArchiveDownloadButtonHelper.bindItem(
mContext,
"云存档-我的分享",
mFragment,
mPackageName,
mGameEntity?.getUniquePackageName() ?: "",
entity,
actionTv
actionTv,
mGameEntity
) {
if (mContext is CloudArchiveManagerActivity) {
(mContext as CloudArchiveManagerActivity).updateMyArchive()

View File

@ -37,7 +37,7 @@ open class MyArchiveFragment : ListFragment<ArchiveEntity, CloudArchiveManagerVi
this,
provideListViewModel(),
mType,
mGameEntity?.getUniquePackageName() ?: ""
mGameEntity
)
}

View File

@ -14,21 +14,22 @@ import com.gh.common.util.NewFlatLogUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.fragment.BaseDialogFragment
import com.gh.gamecenter.common.eventbus.EBReuse
import com.gh.gamecenter.common.utils.DialogHelper
import com.gh.gamecenter.common.utils.goneIf
import com.gh.gamecenter.common.utils.setRootBackgroundDrawable
import com.gh.gamecenter.common.utils.toColor
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.runOnIoThread
import com.gh.gamecenter.databinding.DialogEditArchiveBinding
import com.gh.gamecenter.databinding.DialogMyArchiveOptionBinding
import com.gh.gamecenter.databinding.DialogShareArchiveBinding
import com.gh.gamecenter.entity.ArchiveEntity
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.vspace.VArchiveHelper
import com.halo.assistant.HaloApp
import com.lightgame.download.FileUtils
import org.greenrobot.eventbus.EventBus
class MyArchiveOptionDialogFragment(private val mViewModel: CloudArchiveManagerViewModel) : BaseDialogFragment() {
class MyArchiveOptionDialogFragment(
private val mViewModel: CloudArchiveManagerViewModel,
private val mGameEntity: GameEntity?
) : BaseDialogFragment() {
private lateinit var mBinding: DialogMyArchiveOptionBinding
private var mType = MyArchiveFragment.Type.MY_ARCHIVE
@ -51,6 +52,11 @@ class MyArchiveOptionDialogFragment(private val mViewModel: CloudArchiveManagerV
mBinding.shareTv.goneIf(mType != MyArchiveFragment.Type.MY_ARCHIVE)
mBinding.deleteTv.setOnClickListener {
NewFlatLogUtils.logCloudArchiveDeleteDialogShow()
SensorsBridge.trackEvent(
"CloudSaveDeleteDialogShow",
"game_id", mGameEntity?.id ?: "",
"game_name", mGameEntity?.name ?: ""
)
DialogHelper.showDialog(
requireContext(),
"提示",
@ -60,6 +66,12 @@ class MyArchiveOptionDialogFragment(private val mViewModel: CloudArchiveManagerV
"取消",
confirmClickCallback = {
NewFlatLogUtils.logCloudArchiveDeleteDialogClick("确定")
SensorsBridge.trackEvent(
"CloudSaveDeleteDialogClick",
"game_id", mGameEntity?.id ?: "",
"game_name", mGameEntity?.name ?: "",
"button_name", "确定"
)
mArchiveEntity?.let { entity ->
when (mType) {
MyArchiveFragment.Type.MY_ARCHIVE -> {
@ -83,6 +95,12 @@ class MyArchiveOptionDialogFragment(private val mViewModel: CloudArchiveManagerV
},
cancelClickCallback = {
NewFlatLogUtils.logCloudArchiveDeleteDialogClick("取消")
SensorsBridge.trackEvent(
"CloudSaveDeleteDialogClick",
"game_id", mGameEntity?.id ?: "",
"game_name", mGameEntity?.name ?: "",
"button_name", "取消"
)
},
uiModificationCallback = {
it.confirmTv.setTextColor(R.color.theme_red.toColor(requireContext()))
@ -97,6 +115,11 @@ class MyArchiveOptionDialogFragment(private val mViewModel: CloudArchiveManagerV
}
mBinding.shareTv.setOnClickListener {
NewFlatLogUtils.logCloudArchiveShareDialogShow()
SensorsBridge.trackEvent(
"CloudSaveShareDialogShow",
"game_id", mGameEntity?.id ?: "",
"game_name", mGameEntity?.name ?: ""
)
showShareDialog()
dismissAllowingStateLoss()
}
@ -172,10 +195,22 @@ class MyArchiveOptionDialogFragment(private val mViewModel: CloudArchiveManagerV
mViewModel.shareArchive(entity, titleEt.text.toString().trim(), descEt.text.toString().trim())
}
NewFlatLogUtils.logCloudArchiveShareDialogClick("分享")
SensorsBridge.trackEvent(
"CloudSaveShareDialogClick",
"game_id", mGameEntity?.id ?: "",
"game_name", mGameEntity?.name ?: "",
"button_name", "分享"
)
dialog.dismiss()
}
cancelTv.setOnClickListener {
NewFlatLogUtils.logCloudArchiveShareDialogClick("取消")
SensorsBridge.trackEvent(
"CloudSaveShareDialogClick",
"game_id", mGameEntity?.id ?: "",
"game_name", mGameEntity?.name ?: "",
"button_name", "取消"
)
dialog.dismiss()
}
}
@ -228,9 +263,10 @@ class MyArchiveOptionDialogFragment(private val mViewModel: CloudArchiveManagerV
activity: AppCompatActivity,
mViewModel: CloudArchiveManagerViewModel,
archiveType: MyArchiveFragment.Type,
archiveEntity: ArchiveEntity
archiveEntity: ArchiveEntity,
gameEntity: GameEntity?
) {
MyArchiveOptionDialogFragment(mViewModel).apply {
MyArchiveOptionDialogFragment(mViewModel, gameEntity).apply {
arguments = bundleOf(
KEY_ARCHIVE_TYPE to archiveType.value,
KEY_ARCHIVE to archiveEntity

View File

@ -7,9 +7,6 @@ import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.constant.Config
import com.gh.common.databind.BindingAdapters
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.feature.exposure.ExposureSource
import com.gh.gamecenter.feature.exposure.ExposureType
import com.gh.common.exposure.IExposable
import com.gh.common.util.DirectUtils
import com.gh.common.util.DownloadItemUtils
@ -34,12 +31,15 @@ import com.gh.gamecenter.databinding.ItemRecommendInterestImageBinding
import com.gh.gamecenter.discovery.DiscoveryFragment.Companion.INTERESTED_GAME_REQUEST_CODE
import com.gh.gamecenter.discovery.interestedgame.InterestedGameActivity
import com.gh.gamecenter.entity.DiscoveryGameCardLabel
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.gh.gamecenter.eventbus.EBSkip
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.feature.exposure.ExposureSource
import com.gh.gamecenter.feature.exposure.ExposureType
import com.gh.gamecenter.feature.game.GameItemViewHolder
import com.gh.gamecenter.fragment.MainWrapperFragment
import com.gh.gamecenter.fragment.MainWrapperRepository
import com.gh.gamecenter.feature.game.GameItemViewHolder
import com.lightgame.download.DownloadEntity
import org.greenrobot.eventbus.EventBus
@ -248,7 +248,8 @@ class DiscoveryAdapter(
position,
label.text ?: "",
label.type ?: "",
label.link ?: ""
label.link ?: "",
"发现详情页"
)
}
@ -315,8 +316,6 @@ class DiscoveryAdapter(
gameKaifuType.setBackgroundColor(R.color.theme.toColor(root.context))
gameName.setTextColor(R.color.text_title.toColor(root.context))
gameDes.setTextColor(R.color.text_subtitleDesc.toColor(root.context))
downloadSpeed.setTextColor(R.color.text_subtitleDesc.toColor(root.context))
downloadPercentage.setTextColor(R.color.theme_font.toColor(root.context))
gameIconView.displayGameIcon(gameEntity)
BindingAdapters.setGameName(gameName, gameEntity, false, null)
@ -338,8 +337,6 @@ class DiscoveryAdapter(
gameDes.visibleIf(gameEntity.recommendTag.isNotEmpty()) {
gameDes.text = "根据 “${gameEntity.recommendTag}” 兴趣推荐"
}
//type: recommend 专题游戏 | ad 广告游戏 | filter 算法游戏
adLabelTv.goneIf(!(gameEntity.type == "ad" && gameEntity.adIconActive))
if (gameEntity.type == "ad" && gameEntity.adIconActive) {
recommendReasonTv.visibility = View.GONE
} else {
@ -360,11 +357,15 @@ class DiscoveryAdapter(
recommendReasonTv.visibility = View.VISIBLE
}
}
GameItemViewHolder.initGameSubtitle(gameEntity, gameSubtitleTv) {
gameDesSpace.post {
gameSubtitleTv.maxWidthExcludeZero(if (gameEntity.type == "ad" && gameEntity.adIconActive) gameDesSpace.width - 25F.dip2px() else gameDesSpace.width)
}
}
//type: recommend 专题游戏 | ad 广告游戏 | filter 算法游戏
GameItemViewHolder.initGameSubtitleAndAdLabel(
gameEntity,
gameSubtitleTv,
gameNameContainer,
gameName,
gameEntity.type == "ad" && gameEntity.adIconActive,
adLabelTv
)
}
}
}

View File

@ -57,6 +57,9 @@ class DiscoveryFragment : LazyListFragment<DiscoveryItemData, DiscoveryViewModel
private var mPageBottomVisibleCount = 0
private lateinit var mExposureListener: ExposureListener
//下拉刷新次数
private var mRefreshCount = 0
private val dataWatcher = object : DataWatcher() {
override fun onDataChanged(downloadEntity: DownloadEntity) {
mAdapter?.notifyItemByDownload(downloadEntity)
@ -75,6 +78,11 @@ class DiscoveryFragment : LazyListFragment<DiscoveryItemData, DiscoveryViewModel
mCachedView.setBackgroundColor(R.color.background_white.toColor(requireContext()))
}
override fun onRefresh() {
super.onRefresh()
NewFlatLogUtils.logDiscoverPageDropDownRefresh(++mRefreshCount)
}
override fun initSkeletonScreen() {
if (mSkeletonScreenView == null) return
mSkeletonScreen = Skeleton.bind(mSkeletonScreenView)

View File

@ -161,7 +161,8 @@ public class GameDownloadFragment extends BaseFragment implements View.OnClickLi
adapter.notifyItemChanged(adapter.getBase() + location + 1);
}
}
if (downloadEntity.getStatus() == DownloadStatus.neterror) {
if (downloadEntity.getStatus() == DownloadStatus.neterror
|| downloadEntity.getStatus() == DownloadStatus.diskisfull) {
adapter.notifyItemChanged(adapter.getBase());
}
} else {

View File

@ -231,6 +231,7 @@ class GameDownloadFragmentAdapter extends BaseRecyclerAdapter<ViewHolder> {
} else if (status.equals(DownloadStatus.pause)
|| status.equals(DownloadStatus.timeout)
|| status.equals(DownloadStatus.neterror)
|| status.equals(DownloadStatus.diskisfull)
|| status.equals(DownloadStatus.subscribe)) {
viewHolder.binding.dmItemTvStartorpause.setText(R.string.resume);
viewHolder.binding.dmItemTvStartorpause.setButtonStyle(DownloadButton.ButtonStyle.NORMAL);
@ -240,6 +241,8 @@ class GameDownloadFragmentAdapter extends BaseRecyclerAdapter<ViewHolder> {
|| status.equals(DownloadStatus.neterror)
|| status.equals(DownloadStatus.subscribe)) {
viewHolder.binding.dmItemTvSpeed.setText("等待WIFI");
} else if (status.equals(DownloadStatus.diskisfull)) {
viewHolder.binding.dmItemTvSpeed.setText("已暂停,磁盘空间不足");
} else {
viewHolder.binding.dmItemTvSpeed.setText("已暂停");
}

View File

@ -0,0 +1,13 @@
package com.gh.gamecenter.entity
import android.os.Parcelable
import com.google.gson.annotations.SerializedName
import kotlinx.parcelize.Parcelize
@Parcelize
data class DefaultAvatar(
@SerializedName("_id")
val id: String = "",
val url: String = "",
val order: String = ""
) : Parcelable

View File

@ -1,11 +1,13 @@
package com.gh.gamecenter.entity
import android.os.Parcelable
import com.gh.gamecenter.common.entity.LinkEntity
import com.gh.gamecenter.feature.entity.MeEntity
import com.gh.gamecenter.feature.entity.SimpleGame
import com.gh.gamecenter.feature.entity.UserEntity
import com.gh.gamecenter.feature.entity.ZoneEntity
import com.google.gson.annotations.SerializedName
import kotlinx.parcelize.Parcelize
class ForumDetailEntity(
@SerializedName("_id")
@ -21,7 +23,11 @@ class ForumDetailEntity(
var zone: ZoneEntity? = null,
var me: MeEntity = MeEntity(),
var type: String = "", //game_bbs/official_bbs
var hot: Int = 0 // 热度值
var hot: Int = 0, // 热度值
@SerializedName("hot_rank")
var hotRank: Int = 0, // 热度排名
@SerializedName("background_layer_color")
var backgroundLayerColor: String = "" // 背景图色值
) {
class TopLinkEntity(
@ -41,6 +47,13 @@ class ForumDetailEntity(
var fontColor: String = ""
)
@Parcelize
class Section(
@SerializedName("_id")
var id: String = "",
var name: String = ""
) : Parcelable
fun convertForumDetailEntityToForumEntity(): ForumEntity {
val forumEntity = ForumEntity()
forumEntity.id = id

View File

@ -24,6 +24,8 @@ data class HomeContent(
val recommendText: String = "",
@SerializedName("common_collection")
val commonCollection: CommonCollectionEntity? = null,
@SerializedName("column_test_v2_data")
val testV2Data: HomeItemTestV2Entity? = null,
val image: String = "",
@SerializedName("first_line_recommend")
val firstLineRecommend: String = "",

View File

@ -0,0 +1,100 @@
package com.gh.gamecenter.entity
import android.os.Parcelable
import androidx.annotation.Keep
import androidx.room.Entity
import com.gh.gamecenter.common.entity.LinkEntity
import com.gh.gamecenter.feature.entity.GameEntity
import com.google.gson.annotations.Expose
import com.google.gson.annotations.SerializedName
import kotlinx.parcelize.Parcelize
/**
* @author : liujiarui
* date : 2023/3/3
* description : 首页-推荐tab-新游开测 item 实体类
*/
@Keep
@Entity
@Parcelize
data class HomeItemTestV2Entity(
@SerializedName("action")
val action: String = "",
@SerializedName("count")
val count: Int = 0,
@SerializedName("limit")
val limit: Int = 0,
@SerializedName("page_id")
val pageId: String = "",
@SerializedName("recommend_label")
val recommendLabel: List<RecommendLabel> = listOf(),
@SerializedName("right_top")
val rightTop: RightTop = RightTop(),
@SerializedName("start_id")
val startId: String = "",
@SerializedName("start_point")
val startPoint: Map<String, String> = mapOf(), // key 时间轴名称value 当前时间轴第一个游戏id
@SerializedName("data_count")
val dataCount: Map<String, Int> = mapOf(), //key 时间轴名称value 当前时间轴所包含的游戏数量
@SerializedName("time_type")
val timeType: String = "",
// 首屏游戏列表
val data: List<GameData> = emptyList(),
// 用来判断是不是下拉刷新
@Expose(serialize = false, deserialize = false)
var isRefresh: Boolean = true
) : Parcelable
@Keep
@Entity
@Parcelize
data class RecommendLabel(
@SerializedName("_id")
val id: String = "",
@SerializedName("link")
val link: LinkEntity = LinkEntity(),
@SerializedName("text")
val text: String = ""
) : Parcelable
@Keep
@Entity
@Parcelize
data class RightTop(
@SerializedName("link")
val link: LinkEntity = LinkEntity(),
@SerializedName("text")
val text: String = ""
) : Parcelable
@Keep
@Entity
@Parcelize
data class GameData(
@SerializedName("start_midnight")
val startMidnight: Long = 0L,
@SerializedName("time_type")
val timeType: String = "",//时间轴recommend推荐、xxxx-xx-xx全部比如2023-01-01
var games: List<GameEntity> = emptyList()
) : Parcelable
/**
* 新游开测游戏列表包装类
*/
@Keep
data class GameDataWrapper(
var index: Int,
val timeType: String = "",
val gameData: GameEntity? = null,
var isPlaceHolder: Boolean = false, //占位标识
var isSpace: Boolean = false, //空条目标识
) {
override fun toString(): String {
return "index = $index, " +
"timeType = $timeType, " +
"gameId = ${gameData?.id}, " +
"gameName = ${gameData?.name}"
}
}

View File

@ -42,7 +42,10 @@ data class LibaoEntity(
@SerializedName("activity_link")
var activityLink: ActivityLink = ActivityLink(), //关联活动链接数据
@SerializedName("app_and_plugin_hide")
var appAndPluginHide: Boolean = false, //app和插件内不显示
var appAndPluginHide: Boolean = false, // app和插件内不显示
@SerializedName("receive_method")
var receiveMethod: String = "", // 当值为 copy 时,仅领取不能进入详情
var toast: String = "", // 点击游戏详情页的领取按钮时的 toast 内容
//本地字段
var clickReceiveBtnIn: Boolean = false//是否是点击列表领取按钮进入

View File

@ -11,7 +11,8 @@ class NewApiSettingsEntity(
var startAd: StartupAdEntity? = null,//开屏图片广告
var startup: StartupAdEntity? = null,//启动文案广告
@SerializedName("user_interested_game")
var userInterestedGame: Boolean = false //偏好设置状态开关
var userInterestedGame: Boolean = false, //偏好设置状态开关
var install: Install, // 安装相关的
) {
/**
*
@ -24,4 +25,17 @@ class NewApiSettingsEntity(
val setting: Boolean,
val install: Boolean
)
// VPN 配置
class Install(
@SerializedName("vpn_required")
val vpnRequired: VpnSetting? = null
)
class VpnSetting(
@SerializedName("current_device")
val shouldShowVpnOption: Boolean,
@SerializedName("packages")
val vpnMatchedPackagesName: HashSet<String>
)
}

View File

@ -0,0 +1,3 @@
package com.gh.gamecenter.entity
data class SensorsEvent(var name: String = "", var kv: String = "")

View File

@ -11,5 +11,8 @@ class StartupAdEntity(
val jump: LinkEntity,
val img: String = "",
// 显示规则: none无, each每一次打开, everyday每一天一次, once一次
val rule: String = ""
)
val rule: String = "",
val time: TimeEntity? = null
) {
class TimeEntity(val start: Long = 0, val end: Long = 0)
}

View File

@ -43,6 +43,9 @@ data class SubjectEntity(
@SerializedName("game_list_collection")
var gameListCollection: List<GamesCollectionEntity>? = null,
@SerializedName("column_test_v2_data")
val testV2Data: HomeItemTestV2Entity? = null,
@SerializedName("show_name")
var showName: Boolean = true, // 是否显示“专题名字”true、false
@SerializedName("show_suffix")

View File

@ -17,6 +17,10 @@ import com.gh.gamecenter.common.baselist.ListAdapter
import com.gh.gamecenter.common.utils.goneIf
import com.gh.gamecenter.databinding.CommunityAnswerItemBinding
import com.gh.gamecenter.common.entity.CommunityEntity
import com.gh.gamecenter.common.utils.toBinding
import com.gh.gamecenter.common.utils.toColor
import com.gh.gamecenter.common.utils.toDrawable
import com.gh.gamecenter.databinding.ItemForumArticleHeadBinding
import com.gh.gamecenter.forum.home.ForumArticleAskItemViewHolder
import com.gh.gamecenter.qa.article.detail.ArticleDetailActivity
import com.gh.gamecenter.feature.entity.AnswerEntity
@ -24,15 +28,29 @@ import com.gh.gamecenter.feature.entity.Questions
import com.gh.gamecenter.qa.questions.newdetail.NewQuestionDetailActivity
import com.gh.gamecenter.qa.video.detail.ForumVideoDetailActivity
class ForumArticleAskListAdapter(context: Context, val bbsId: String, val mEntrance: String, val path: String) :
class ForumArticleAskListAdapter(
context: Context,
val bbsId: String,
val entrance: String,
val path: String,
val viewModel: ForumArticleAskListViewModel,
val onCheckCallback: (String) -> Unit
) :
ListAdapter<AnswerEntity>(context), ISyncAdapterHandler {
private var mDefOrderList = listOf("回复", "发布")
private var mVideoOrderList = listOf("推荐", "发布")
private var mFilterPosition = 0
override fun areItemsTheSame(oldItem: AnswerEntity?, newItem: AnswerEntity?): Boolean {
return oldItem?.id == newItem?.id
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return when (viewType) {
ItemViewType.ITEM_HEADER -> {
ForumArticleHeadViewHolder(parent.toBinding())
}
ItemViewType.ITEM_FOOTER -> {
FooterViewHolder(mLayoutInflater.inflate(R.layout.refresh_footerview, parent, false))
}
@ -51,6 +69,7 @@ class ForumArticleAskListAdapter(context: Context, val bbsId: String, val mEntra
}
override fun getItemViewType(position: Int): Int {
if (position == 0) return ItemViewType.ITEM_HEADER
if (position == itemCount - 1) return ItemViewType.ITEM_FOOTER
return ItemViewType.ITEM_BODY
}
@ -62,6 +81,7 @@ class ForumArticleAskListAdapter(context: Context, val bbsId: String, val mEntra
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (getItemViewType(position)) {
ItemViewType.ITEM_BODY -> {
val articlePosition = position - 1
val answer = mEntityList[position]
if (answer.type != "answer") {
val questions = Questions()
@ -80,7 +100,7 @@ class ForumArticleAskListAdapter(context: Context, val bbsId: String, val mEntra
val answerViewHolder = holder as ForumArticleAskItemViewHolder
val binding = answerViewHolder.binding
binding.forumNameLl.visibility = View.GONE
binding.topLine.goneIf(position == 0)
binding.topLine.goneIf(articlePosition == 0)
val params = binding.includeVoteAndComment.root.layoutParams as LinearLayout.LayoutParams
params.width = LinearLayout.LayoutParams.MATCH_PARENT
@ -89,12 +109,12 @@ class ForumArticleAskListAdapter(context: Context, val bbsId: String, val mEntra
binding.includeVoteAndComment.root.layoutParams = params
val tabInfo = "${path}tab"
answerViewHolder.bindForumAnswerItem(answer, mEntrance, path, position)
answerViewHolder.bindForumAnswerItem(answer, entrance, path, articlePosition)
answerViewHolder.itemView.setOnClickListener {
val entrance = BaseActivity.mergeEntranceAndPath(mEntrance, path)
val entrance = BaseActivity.mergeEntranceAndPath(entrance, path)
val userId = answer.user.id ?: ""
val contentId = answer.id ?: ""
val sequence = position + 1
val sequence = articlePosition + 1
val bbsType = if (answer.bbs.type == "official_bbs") "综合论坛" else "游戏论坛"
when (answer.type) {
"community_article" -> {
@ -118,7 +138,7 @@ class ForumArticleAskListAdapter(context: Context, val bbsId: String, val mEntra
mContext,
CommunityEntity(bbsId),
answer.id!!,
mEntrance,
entrance,
path
)
)
@ -160,7 +180,7 @@ class ForumArticleAskListAdapter(context: Context, val bbsId: String, val mEntra
mContext.startActivity(
NewQuestionDetailActivity.getIntent(
mContext, answer.id
?: "", mEntrance, path
?: "", entrance, path
)
)
}
@ -183,7 +203,7 @@ class ForumArticleAskListAdapter(context: Context, val bbsId: String, val mEntra
mContext.startActivity(
NewQuestionDetailActivity.getCommentIntent(
mContext, answer.questions.id, answer.id
?: "", mEntrance, path
?: "", entrance, path
)
)
}
@ -197,6 +217,31 @@ class ForumArticleAskListAdapter(context: Context, val bbsId: String, val mEntra
footerViewHolder.hint.textSize = 12f
footerViewHolder.hint.setTextColor(ContextCompat.getColor(mContext, R.color.aaaaaa))
}
ItemViewType.ITEM_HEADER -> {
if (holder is ForumArticleHeadViewHolder) {
val articleListHead = if (path == "全部") {
viewModel.selectedSection.name
} else path
holder.binding.root.setBackgroundColor(R.color.background_white.toColor(mContext))
holder.binding.articleListHeadTv.setTextColor(R.color.text_title.toColor(mContext))
holder.binding.articleListHeadTv.text = "${articleListHead}列表"
holder.binding.orderSfv.run {
setContainerBackground(R.drawable.button_round_f5f5f5.toDrawable(mContext))
setIndicatorBackground(R.drawable.bg_game_collection_sfv_indicator.toDrawable(mContext))
setTextColor(
R.color.text_subtitle.toColor(mContext),
R.color.text_subtitleDesc.toColor(mContext)
)
setItemList(if (path == "视频") mVideoOrderList else mDefOrderList, mFilterPosition)
setOnCheckedCallback { position ->
mFilterPosition = position
onCheckCallback.invoke((if (path == "视频") mVideoOrderList else mDefOrderList)[position])
}
}
}
}
}
}
@ -205,4 +250,6 @@ class ForumArticleAskListAdapter(context: Context, val bbsId: String, val mEntra
val entity = mEntityList[position]
return Pair(entity.id ?: "", entity)
}
class ForumArticleHeadViewHolder(val binding: ItemForumArticleHeadBinding) : RecyclerView.ViewHolder(binding.root)
}

View File

@ -18,6 +18,7 @@ import com.gh.gamecenter.core.AppExecutor
import com.gh.gamecenter.core.iinterface.IScrollable
import com.gh.gamecenter.core.utils.MD5Utils
import com.gh.gamecenter.databinding.FragmentListBaseSkeletonBinding
import com.gh.gamecenter.entity.ForumDetailEntity
import com.gh.gamecenter.eventbus.EBDeleteDetail
import com.gh.gamecenter.eventbus.EBTypeChange
import com.gh.gamecenter.eventbus.EBUserFollow
@ -39,6 +40,9 @@ class ForumArticleAskListFragment : LazyListFragment<AnswerEntity, ForumArticleA
private var bbsId: String = ""
private var mListReachTop = true
var filter = "回复"
var videoFilter = "推荐"
override fun getRealLayoutId(): Int = R.layout.fragment_list_base_skeleton
override fun onRealLayoutInflated(inflatedView: View) {
@ -47,8 +51,10 @@ class ForumArticleAskListFragment : LazyListFragment<AnswerEntity, ForumArticleA
}
override fun provideListViewModel(): ForumArticleAskListViewModel {
val factory = ForumArticleAskListViewModel.Factory(bbsId, mPath)
mViewModel = viewModelProvider(factory)
if (mViewModel == null) {
val factory = ForumArticleAskListViewModel.Factory(bbsId, mPath)
mViewModel = viewModelProvider(factory)
}
return mViewModel!!
}
@ -56,8 +62,11 @@ class ForumArticleAskListFragment : LazyListFragment<AnswerEntity, ForumArticleA
requireContext(),
bbsId,
mEntrance,
mPath
).apply { mAdapter = this }
mPath,
mViewModel!!
) {
onRefresh(it)
}.apply { mAdapter = this }
override fun getItemDecoration() = null
@ -167,9 +176,11 @@ class ForumArticleAskListFragment : LazyListFragment<AnswerEntity, ForumArticleA
fun onRefresh(filter: String) {
if (mPath == "全部" || mPath == "问答") {
this.filter = filter
mViewModel?.sort = if (filter == "发布") "time.create" else "time.reply"
}
if (mPath == "视频") {
videoFilter = filter
mViewModel?.videoSort = if (filter == "推荐") "recommend" else "time.upload"
}
onRefresh()
@ -186,22 +197,26 @@ class ForumArticleAskListFragment : LazyListFragment<AnswerEntity, ForumArticleA
mAdapter?.run {
if (entityList == null) return
if (entityList.size == 0) {
mListRv?.visibility = View.VISIBLE
mReuseNoData?.visibility = View.GONE
mReuseNoConn?.visibility = View.GONE
}
entityList.add(0, entity)
notifyDataSetChanged()
mViewModel?.videoList?.add(0, entity.transformForumVideoEntity())
mListRv?.scrollToPosition(0)
mBaseHandler.postDelayed({
tryCatchInRelease {
scroll()
mScrollCalculatorHelper?.onScrollStateChanged(mListRv, RecyclerView.SCROLL_STATE_IDLE)
// 在选择对应子版块或选择全部时才插入数据
if (entity.sectionIdList.contains(mViewModel?.selectedSection?.id) || mViewModel?.selectedSection?.id.isNullOrEmpty()) {
if (entityList.size == 0) {
mListRv?.visibility = View.VISIBLE
mReuseNoData?.visibility = View.GONE
mReuseNoConn?.visibility = View.GONE
entityList.add(AnswerEntity())
}
}, 100)
entityList.add(1, entity)
notifyDataSetChanged()
mViewModel?.videoList?.add(0, entity.transformForumVideoEntity())
mListRv?.scrollToPosition(1)
mBaseHandler.postDelayed({
tryCatchInRelease {
scroll()
mScrollCalculatorHelper?.onScrollStateChanged(mListRv, RecyclerView.SCROLL_STATE_IDLE)
}
}, 100)
}
}
}
@ -308,6 +323,11 @@ class ForumArticleAskListFragment : LazyListFragment<AnswerEntity, ForumArticleA
}
}
fun setSection(section: ForumDetailEntity.Section) {
mViewModel?.selectedSection = section
onRefresh()
}
override fun onDarkModeChanged() {
super.onDarkModeChanged()
mAdapter?.run { notifyItemRangeChanged(0, itemCount) }

View File

@ -8,6 +8,7 @@ import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.core.utils.PageSwitchDataHelper
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.core.utils.UrlFilterUtils
import com.gh.gamecenter.entity.ForumDetailEntity
import com.gh.gamecenter.feature.entity.ForumVideoEntity
import com.gh.gamecenter.feature.entity.AnswerEntity
import com.gh.gamecenter.retrofit.RetrofitManager
@ -18,6 +19,8 @@ class ForumArticleAskListViewModel(application: Application, val bbsId: String =
ListViewModel<AnswerEntity, AnswerEntity>(application) {
var sort: String = "time.reply"
var filter: String = "section_id"
var selectedSection = ForumDetailEntity.Section("", "全部")
var videoSort: String = "recommend"
var videoList = arrayListOf<ForumVideoEntity>()
@ -27,6 +30,10 @@ class ForumArticleAskListViewModel(application: Application, val bbsId: String =
val data = PageSwitchDataHelper.popLastPageData()
val map = hashMapOf<String, Any?>()
if (selectedSection.id.isNotEmpty()) {
map["filter"] = UrlFilterUtils.getFilterQuery(filter, selectedSection.id)
}
if (data != null && data.containsKey(EntranceConsts.KEY_TOP_ID)) {
map["top_id"] = data[EntranceConsts.KEY_TOP_ID]
}
@ -79,7 +86,7 @@ class ForumArticleAskListViewModel(application: Application, val bbsId: String =
it.transformForumVideoEntity()
})
mResultLiveData.postValue(list)
mResultLiveData.postValue(ArrayList(list).apply { add(0, AnswerEntity().apply { id = "" }) })
}
}

View File

@ -52,6 +52,15 @@ class ForumDetailActivity : BaseActivity() {
intent.putExtra(EntranceConsts.KEY_ENTRANCE, entrance)
return intent
}
@JvmStatic
fun getTrendsIntent(context: Context, bbsId: String, entrance: String): Intent {
val intent = Intent(context, ForumDetailActivity::class.java)
intent.putExtra(EntranceConsts.KEY_BBS_ID, bbsId)
intent.putExtra(EntranceConsts.KEY_SCROLL_TO_TRENDS, true)
intent.putExtra(EntranceConsts.KEY_ENTRANCE, entrance)
return intent
}
}
override fun handleBackPressed(): Boolean {

View File

@ -4,7 +4,9 @@ import android.animation.ValueAnimator
import android.app.Activity
import android.content.Intent
import android.graphics.Bitmap
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.GradientDrawable
import android.os.Build
import android.os.Bundle
import android.view.Gravity
@ -12,14 +14,23 @@ import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.animation.AnimationUtils
import android.widget.ImageView
import android.widget.LinearLayout
import android.widget.PopupWindow
import android.widget.TextView
import androidx.annotation.RequiresApi
import androidx.appcompat.content.res.AppCompatResources
import androidx.core.content.ContextCompat
import androidx.core.graphics.ColorUtils
import androidx.core.os.bundleOf
import androidx.core.os.postDelayed
import androidx.core.view.ViewCompat
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.DefaultItemAnimator
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.viewpager.widget.PagerAdapter
import com.ethanhua.skeleton.Skeleton
import com.ethanhua.skeleton.ViewSkeletonScreen
import com.facebook.drawee.drawable.ScalingUtils
@ -32,6 +43,7 @@ import com.gh.gamecenter.GameDetailActivity
import com.gh.gamecenter.NewsDetailActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.TrackableDialog
import com.gh.gamecenter.common.base.adapter.FragmentStateAdapter
import com.gh.gamecenter.common.base.fragment.BaseFragment_TabLayout
import com.gh.gamecenter.common.base.fragment.BaseLazyTabFragment
import com.gh.gamecenter.common.callback.BiCallback
@ -40,11 +52,11 @@ import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.entity.CommunityEntity
import com.gh.gamecenter.common.mvvm.Status
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.view.SegmentedFilterView
import com.gh.gamecenter.core.iinterface.IScrollable
import com.gh.gamecenter.core.runOnUiThread
import com.gh.gamecenter.core.utils.*
import com.gh.gamecenter.databinding.FragmentForumDetailBinding
import com.gh.gamecenter.databinding.PopupForumDetailSectionsBinding
import com.gh.gamecenter.entity.*
import com.gh.gamecenter.eventbus.EBForumFollowChange
import com.gh.gamecenter.eventbus.EBTypeChange
@ -52,15 +64,17 @@ import com.gh.gamecenter.forum.home.CommunityHomeFragment
import com.gh.gamecenter.forum.moderator.ApplyModeratorActivity
import com.gh.gamecenter.forum.moderator.ModeratorListActivity
import com.gh.gamecenter.forum.search.ForumOrUserSearchActivity
import com.gh.gamecenter.gamedetail.GameDetailFragment
import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.qa.article.edit.ArticleEditActivity
import com.gh.gamecenter.feature.entity.AnswerEntity
import com.gh.gamecenter.feature.entity.ForumVideoEntity
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.entity.UserEntity
import com.gh.gamecenter.gamedetail.fuli.FuLiFragment
import com.gh.gamecenter.qa.questions.edit.QuestionEditActivity
import com.gh.gamecenter.qa.video.publish.VideoPublishActivity
import com.google.android.material.appbar.AppBarLayout
import com.halo.assistant.fragment.WebFragment
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
@ -70,24 +84,28 @@ class ForumDetailFragment : BaseLazyTabFragment(), IScrollable {
private var mAllForumArticleAskListFragment: ForumArticleAskListFragment? = null
private var mEssenceForumArticleAskListFragment: ForumArticleAskListFragment? = null
private var mTrendsFragment: Fragment? = null
private var mAskForumArticleAskListFragment: ForumArticleAskListFragment? = null
private var mVideoForumArticleAskListFragment: ForumArticleAskListFragment? = null
private var mBbsId: String = ""
private var mBbsType: String = ""
private var mSectionId: String = ""
private var mViewModel: ForumDetailViewModel? = null
private var mForumDetail: ForumDetailEntity? = null
private var mForumSectionAdapter: ForumSectionAdapter? = null
private var mPopupWindow: PopupWindow? = null
private lateinit var mBinding: FragmentForumDetailBinding
private lateinit var mSkeleton: ViewSkeletonScreen
private var mFilter = "回复"
private var mVideoFilter = "推荐"
private var mLastPosition = 0
private var mAppbarReachTop = true
private var mDefOrderList = listOf("回复", "发布")
private var mVideoOrderList = listOf("推荐", "发布")
private var mIsExpand = false
private var mStatus: ApplyModeratorStatusEntity = ApplyModeratorStatusEntity()
private var mIsToolbarWhite = false
private var mShowSections = false
private var mAskIndex = INDEX_ASK
private var mVideoIndex = INDEX_VIDEO
override fun initFragmentList(fragments: MutableList<Fragment>) {
mAllForumArticleAskListFragment = ForumArticleAskListFragment().with(
@ -128,6 +146,9 @@ class ForumDetailFragment : BaseLazyTabFragment(), IScrollable {
"精华" -> {
mEssenceForumArticleAskListFragment = fragment as ForumArticleAskListFragment
}
"专区" -> {
mTrendsFragment = fragment
}
"问答" -> {
mAskForumArticleAskListFragment = fragment as ForumArticleAskListFragment
}
@ -144,6 +165,10 @@ class ForumDetailFragment : BaseLazyTabFragment(), IScrollable {
tabTitleList.add(TAB_TITLE_VIDEO)
}
override fun providePagerAdapter(): PagerAdapter {
return FragmentStateAdapter(childFragmentManager, mFragmentsList, mTabTitleList)
}
override fun getInflatedLayout(): View {
mBinding = FragmentForumDetailBinding.bind(layoutInflater.inflate(R.layout.fragment_forum_detail, null, false))
return mBinding.root
@ -152,6 +177,7 @@ class ForumDetailFragment : BaseLazyTabFragment(), IScrollable {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mBbsId = arguments?.getString(EntranceConsts.KEY_BBS_ID, "") ?: ""
mSectionId = arguments?.getString(EntranceConsts.KEY_BBS_SECTION_ID, "") ?: ""
val factory = ForumDetailViewModel.Factory(mBbsId)
mViewModel = viewModelProvider(factory)
mViewModel?.forumDetail?.observe(this, Observer {
@ -172,6 +198,17 @@ class ForumDetailFragment : BaseLazyTabFragment(), IScrollable {
userId,
entrance = if (mEntrance.contains("游戏详情")) "游戏详情页" else "论坛tab页"
)
mBaseHandler.postDelayed({
SensorsBridge.trackEvent(
"ViewForum",
"bbs_id",
mBbsId,
"forum_name",
mForumDetail?.name ?: "",
"bbs_type",
mBbsType
)
}, 3000)
initUI()
}
} else {
@ -202,12 +239,17 @@ class ForumDetailFragment : BaseLazyTabFragment(), IScrollable {
mAppbarReachTop = abs(verticalOffset) <= 2
if (mViewPager.currentItem < mFragmentsList.size) {
mFragmentsList.safelyGetInRelease(mViewPager.currentItem)?.run {
mBinding.refreshLayout.isEnabled = mAppbarReachTop
&& (this as ForumArticleAskListFragment).isListReachTop()
if (this is ForumArticleAskListFragment) {
mBinding.refreshLayout.isEnabled = mAppbarReachTop && isListReachTop()
} else {
mBinding.refreshLayout.isEnabled = false
}
}
}
})
initSection()
mSkeleton = Skeleton.bind(mBinding.skeletonContainer)
.shimmer(true)
.angle(Constants.SHIMMER_ANGLE)
@ -269,25 +311,35 @@ class ForumDetailFragment : BaseLazyTabFragment(), IScrollable {
})
mViewPager.doOnPageSelected {
mBinding.run {
allOrderSfv.goneIf(it != INDEX_ALL)
askOrderSfv.goneIf(it != INDEX_ASK)
videoOrderSfv.goneIf(it != INDEX_VIDEO)
sectionContainer.goneIf(it != INDEX_ALL || !mShowSections)
}
MtaHelper.onEvent("论坛详情", getKeyValue(mLastPosition), getKeyValue(it))
mLastPosition = it
if (it < mFragmentsList.size) {
(mFragmentsList.safelyGetInRelease(it) as ForumArticleAskListFragment).refreshScrollHelper()
val fragment = mFragmentsList.safelyGetInRelease(it)
if (fragment is ForumArticleAskListFragment) {
fragment.refreshScrollHelper()
mBinding.refreshLayout.isEnabled = mAppbarReachTop && fragment.isListReachTop()
} else {
mBinding.refreshLayout.isEnabled = false
}
}
when (it) {
INDEX_ALL -> NewLogUtils.logForumDetailEnterOrClick("click_all_tab", mBbsId, mBbsType, "", mFilter)
INDEX_ALL -> NewLogUtils.logForumDetailEnterOrClick(
"click_all_tab",
mBbsId,
mBbsType,
"",
mAllForumArticleAskListFragment?.filter ?: "回复"
)
INDEX_ESSENCE -> NewLogUtils.logForumDetailEnterOrClick("click_essence_tab", mBbsId, mBbsType)
INDEX_ASK -> NewLogUtils.logForumDetailEnterOrClick("click_question_tab", mBbsId, mBbsType)
INDEX_VIDEO -> NewLogUtils.logForumDetailEnterOrClick(
mAskIndex -> NewLogUtils.logForumDetailEnterOrClick("click_question_tab", mBbsId, mBbsType)
mVideoIndex -> NewLogUtils.logForumDetailEnterOrClick(
"click_video_tab",
mBbsId,
mBbsType,
"",
mVideoFilter
mVideoForumArticleAskListFragment?.videoFilter ?: "推荐"
)
}
}
@ -298,16 +350,57 @@ class ForumDetailFragment : BaseLazyTabFragment(), IScrollable {
if (mEssenceForumArticleAskListFragment != null && mViewPager.currentItem == INDEX_ESSENCE) {
mEssenceForumArticleAskListFragment?.refresh()
}
if (mAskForumArticleAskListFragment != null && mViewPager.currentItem == INDEX_ASK) {
if (mAskForumArticleAskListFragment != null && mViewPager.currentItem == mAskIndex) {
mAskForumArticleAskListFragment?.refresh()
}
if (mVideoForumArticleAskListFragment != null && mViewPager.currentItem == INDEX_VIDEO) {
if (mVideoForumArticleAskListFragment != null && mViewPager.currentItem == mVideoIndex) {
mVideoForumArticleAskListFragment?.refresh()
}
}
LogUtils.uploadAccessToBbs(mBbsId, "论坛详情")
}
private fun initSection() {
mForumSectionAdapter = ForumSectionAdapter(requireContext(), mViewModel!!) {
setSection()
}
mBinding.sectionRv.run {
layoutManager = LinearLayoutManager(requireContext(), RecyclerView.HORIZONTAL, false)
adapter = mForumSectionAdapter
(itemAnimator as DefaultItemAnimator).supportsChangeAnimations = false
}
mViewModel?.sectionListLiveData?.observe(this) {
if (!it.isNullOrEmpty() && it.size >= 2) {
mShowSections = true
mBinding.sectionContainer.visibility = View.VISIBLE
if (mSectionId.isNotEmpty()) {
it.forEachIndexed { index, section ->
if (section.id == mSectionId) {
mViewModel?.selectedSection = section
setSection()
mForumSectionAdapter?.submitList(it)
mBinding.sectionRv.scrollToPosition(index)
}
}
} else {
mForumSectionAdapter?.submitList(it)
}
} else {
mShowSections = false
mBinding.sectionContainer.visibility = View.GONE
}
}
}
private fun setSection() {
mAllForumArticleAskListFragment?.setSection(
mViewModel?.selectedSection ?: ForumDetailEntity.Section(
"",
"全部"
)
)
}
fun hideRefreshingLayout() {
mBinding.refreshLayout.isRefreshing = false
}
@ -320,8 +413,9 @@ class ForumDetailFragment : BaseLazyTabFragment(), IScrollable {
return when (position) {
INDEX_ALL -> "全部Tab"
INDEX_ESSENCE -> "精华Tab"
INDEX_ASK -> "问答Tab"
else -> "视频Tab"
mAskIndex -> "问答Tab"
mVideoIndex -> "视频Tab"
else -> "专区Tab"
}
}
@ -331,12 +425,11 @@ class ForumDetailFragment : BaseLazyTabFragment(), IScrollable {
mBinding.forumDefaultBackground.goneIf(background.isNotEmpty())
mBinding.forumMaskDefaultView.goneIf(background.isNotEmpty())
mBinding.moderatorContainer.visibleIf(moderator.isNotEmpty())
mBinding.gameZoneTv.visibleIf(zone != null)
mBinding.gameDetailTv.goneIf(!game.active)
mBinding.forumNameTv.text = name
mBinding.followTv.text = if (me.isFollower) "已关注" else "关注"
mBinding.titleTv.text = name
mBinding.dividerLine.goneIf(topLink.isEmpty())
mBinding.moderatorTv.setPadding(if (moderator.isNotEmpty()) 8f.dip2px() else 0, 0, 0, 0)
mBinding.moderatorTv.text = if (moderator.isNotEmpty()) "版主成员" else "暂无版主,申请成为版主"
if (type == "official_bbs") {
mBinding.forumThumbSmall.displayGameIcon(icon, null)
@ -407,11 +500,66 @@ class ForumDetailFragment : BaseLazyTabFragment(), IScrollable {
requireContext(),
if (me.isFollower) R.drawable.button_round_gray_light else R.drawable.download_button_normal_style
)
mBinding.allOrderSfv.setItemList(mDefOrderList, 0)
mBinding.askOrderSfv.setItemList(mDefOrderList, 0)
mBinding.videoOrderSfv.setItemList(mVideoOrderList, 0)
showModeratorGuide()
if (backgroundLayerColor.isNotEmpty()) {
val colorRGBList =
backgroundLayerColor.substring(4, backgroundLayerColor.length - 1).split(",").map { it.toInt() }
val colorHSV = colorRGBList.colorRGBToHSV().apply {
this[2] *= 0.6F
}
val startColor = Color.HSVToColor(colorHSV)
val endColor = ColorUtils.setAlphaComponent(startColor, 0)
mBinding.forumTopMaskContainer.background = GradientDrawable().apply {
gradientType = GradientDrawable.LINEAR_GRADIENT
orientation = GradientDrawable.Orientation.BOTTOM_TOP
colors = intArrayOf(startColor, endColor)
}
}
mBinding.forumHeatTv.text = "热度值:${NumberUtils.transSimpleCount(hot)}"
mBinding.forumHeatTv.setDrawableEnd(
if (hotRank <= 20) AppCompatResources.getDrawable(
requireContext(),
R.drawable.icon_heat
) else null
)
mBinding.sectionMoreIv.setOnClickListener {
showSectionsPopupWindow()
}
zone?.let {
mTabTitleList.add(INDEX_TRENDS, it.customName.ifEmpty { TAB_TRENDS })
if (it.style == "link") {//显示web页面
val webFragment = childFragmentManager.findFragmentByTag("${tag}$INDEX_TRENDS") ?: WebFragment()
val webBundle = Bundle()
webBundle.putString(EntranceConsts.KEY_ENTRANCE, "游戏专区")
webBundle.putString(EntranceConsts.KEY_URL, it.link)
webBundle.putBoolean(WebFragment.KEY_OPEN_NATIVE_PAGE, true)
webBundle.putString(EntranceConsts.KEY_PATH, TAB_TRENDS)
webFragment.arguments = webBundle
mTrendsFragment = webFragment
mFragmentsList.add(INDEX_TRENDS, webFragment)
} else {
val fuliFragment = childFragmentManager.findFragmentByTag("${tag}$INDEX_TRENDS") ?: FuLiFragment()
fuliFragment.arguments = bundleOf(
GameEntity.TAG to game.toGameEntity(),
EntranceConsts.KEY_ENTRANCE to mEntrance,
EntranceConsts.KEY_PATH to TAB_TRENDS
)
mTrendsFragment = fuliFragment
mFragmentsList.add(INDEX_TRENDS, fuliFragment)
}
mViewPager.adapter?.notifyDataSetChanged()
mAskIndex = INDEX_ASK + 1
mVideoIndex = INDEX_VIDEO + 1
if (arguments?.getBoolean(EntranceConsts.KEY_SCROLL_TO_TRENDS, false) == true) {
mViewPager.currentItem = INDEX_TRENDS
}
}
}
}
@ -462,18 +610,6 @@ class ForumDetailFragment : BaseLazyTabFragment(), IScrollable {
NewLogUtils.logForumDetailEnterOrClick("click_forum_detail_search")
requireContext().startActivity(ForumOrUserSearchActivity.getIntent(requireContext(), mBbsId, "论坛详情"))
}
mBinding.allOrderSfv.setOnCheckedCallback { position ->
mFilter = mDefOrderList[position]
mAllForumArticleAskListFragment?.onRefresh(mDefOrderList[position])
}
mBinding.askOrderSfv.setOnCheckedCallback { position ->
mFilter = mDefOrderList[position]
mAskForumArticleAskListFragment?.onRefresh(mDefOrderList[position])
}
mBinding.videoOrderSfv.setOnCheckedCallback { position ->
mVideoFilter = mVideoOrderList[position]
mVideoForumArticleAskListFragment?.onRefresh(mVideoOrderList[position])
}
mBinding.forumTopContentArrowContainer.setOnClickListener {
mForumDetail?.run {
mBinding.run {
@ -543,16 +679,17 @@ class ForumDetailFragment : BaseLazyTabFragment(), IScrollable {
mSkeleton.show()
mViewModel?.getForumDetail()
mViewModel?.getModeratorsApplyStatus()
mViewModel?.getSections()
}
mBinding.gameZoneTv.setOnClickListener {
NewLogUtils.logForumDetailEnterOrClick("click_strategy_zone", mBbsId, mBbsType)
if (mForumDetail?.zone != null) {
MtaHelper.onEvent("论坛详情", "顶部区域", "游戏专区")
GameDetailActivity.startGameDetailActivity(
requireContext(), mForumDetail?.game?.id ?: "", mEntrance, GameDetailFragment.INDEX_TRENDES
)
}
}
// mBinding.gameZoneTv.setOnClickListener {
// NewLogUtils.logForumDetailEnterOrClick("click_strategy_zone", mBbsId, mBbsType)
// if (mForumDetail?.zone != null) {
// MtaHelper.onEvent("论坛详情", "顶部区域", "游戏专区")
// GameDetailActivity.startGameDetailActivity(
// requireContext(), mForumDetail?.game?.id ?: "", mEntrance, GameDetailFragment.INDEX_TRENDES
// )
// }
// }
mBinding.forumThumbBig.setOnClickListener {
NewLogUtils.logForumDetailEnterOrClick("click_forum_detail_forum_icon", mBbsId)
MtaHelper.onEvent("论坛详情", "顶部区域", "游戏图标")
@ -565,6 +702,15 @@ class ForumDetailFragment : BaseLazyTabFragment(), IScrollable {
}
mBinding.followTv.setOnClickListener {
debounceActionWithInterval(R.id.followTv) {
SensorsBridge.trackEvent(
"FollowForumClick",
"bbs_id",
mBbsId,
"forum_name",
mForumDetail?.name ?: "",
"bbs_type",
mBbsType
)
ifLogin(mEntrance) {
val forumEntity = ForumEntity(
id = mForumDetail?.id ?: "",
@ -613,6 +759,12 @@ class ForumDetailFragment : BaseLazyTabFragment(), IScrollable {
)
)
}
mBinding.gameDetailTv.setOnClickListener {
GameDetailActivity.startGameDetailActivity(
requireContext(), mForumDetail?.game?.id
?: "", "(论坛详情)"
)
}
}
private fun updateToolbarStyle(isToolbarWhite: Boolean) {
@ -682,11 +834,12 @@ class ForumDetailFragment : BaseLazyTabFragment(), IScrollable {
private fun initModeratorHeadView(datas: List<UserEntity>) {
mBinding.moderatorContainer.removeAllViews()
datas.forEachIndexed { index, user ->
datas.take(3).forEachIndexed { index, user ->
val params = LinearLayout.LayoutParams(20F.dip2px(), 20F.dip2px())
val headView = SimpleDraweeView(requireContext())
val roundingParams = RoundingParams().apply {
roundAsCircle = true
setBorder(ContextCompat.getColor(requireContext(), R.color.white), 1f.dip2px().toFloat())
setBorder(ContextCompat.getColor(requireContext(), R.color.white), 1F.dip2px().toFloat())
}
headView.hierarchy = GenericDraweeHierarchyBuilder(resources)
.setFadeDuration(500)
@ -696,7 +849,6 @@ class ForumDetailFragment : BaseLazyTabFragment(), IScrollable {
.setBackground(ColorDrawable(ContextCompat.getColor(requireContext(), R.color.placeholder_bg)))
.setActualImageScaleType(ScalingUtils.ScaleType.CENTER_CROP)
.build()
val params = LinearLayout.LayoutParams(20f.dip2px(), 20f.dip2px())
headView.layoutParams = params
if (index != 0) {
params.leftMargin = (-8f).dip2px()
@ -709,6 +861,16 @@ class ForumDetailFragment : BaseLazyTabFragment(), IScrollable {
mBinding.moderatorContainer.addView(headView)
}
val params = LinearLayout.LayoutParams(20F.dip2px(), 20F.dip2px())
params.leftMargin = (-8F).dip2px()
mBinding.moderatorContainer.addView(ImageView(requireContext()).apply {
layoutParams = params
setImageResource(R.drawable.icon_moderator_more)
setOnClickListener {
MtaHelper.onEvent("论坛详情", "顶部区域", "版主头像")
mBinding.moderatorTv.performClick()
}
})
}
private fun showCommunityEditWindow() {
@ -746,7 +908,8 @@ class ForumDetailFragment : BaseLazyTabFragment(), IScrollable {
icon = mForumDetail?.game?.getIcon(),
iconSubscript = mForumDetail?.game?.iconSubscript
), mForumDetail?.type
?: ""
?: "",
"论坛详情页"
),
ARTICLE_REQUEST_CODE
)
@ -769,7 +932,7 @@ class ForumDetailFragment : BaseLazyTabFragment(), IScrollable {
icon = mForumDetail?.game?.getIcon(),
iconSubscript = mForumDetail?.game?.iconSubscript
), mForumDetail?.type
?: ""
?: "", "论坛详情页"
),
QUESTION_REQUEST_CODE
)
@ -812,6 +975,72 @@ class ForumDetailFragment : BaseLazyTabFragment(), IScrollable {
}
}
private fun showSectionsPopupWindow() {
val binding = PopupForumDetailSectionsBinding.inflate(LayoutInflater.from(requireContext()), null, false)
val popupWindow = PopupWindow(
binding.root,
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT
).apply { mPopupWindow = this }
mViewModel?.sectionListLiveData?.value?.forEachIndexed { index, section ->
val item = getItemTextView(section.name)
binding.flexbox.addView(item)
item.tag = section.name
toggleHighlightedTextView(item, mViewModel?.selectedSection?.id == section.id)
item.setOnClickListener {
toggleHighlightedTextView(item, true)
mViewModel?.selectedSection = section
mAllForumArticleAskListFragment?.setSection(
mViewModel?.selectedSection ?: ForumDetailEntity.Section(
"",
"全部"
)
)
mForumSectionAdapter?.run {
notifyItemRangeChanged(0, itemCount)
}
mBinding.sectionRv.smoothScrollToPosition(index)
popupWindow.dismiss()
}
}
binding.background.setOnClickListener {
popupWindow.dismiss()
mPopupWindow = null
}
binding.closeIv.setOnClickListener {
popupWindow.dismiss()
mPopupWindow = null
}
popupWindow.isTouchable = true
popupWindow.isFocusable = true
popupWindow.animationStyle = 0
popupWindow.showAsDropDown(mBinding.tabContainer, 0, 0)
}
private fun toggleHighlightedTextView(targetTextView: TextView, highlightIt: Boolean) {
if (highlightIt) {
targetTextView.background = R.drawable.button_round_primary_light.toDrawable(requireContext())
targetTextView.setTextColor(R.color.theme_font.toColor(requireContext()))
} else {
targetTextView.background = R.drawable.button_round_gray_light.toDrawable(requireContext())
targetTextView.setTextColor(R.color.text_subtitle.toColor(requireContext()))
}
}
private fun getItemTextView(name: String): TextView {
return TextView(requireContext()).apply {
text = name
includeFontPadding = false
textSize = 12F
gravity = Gravity.CENTER
setPadding(12F.dip2px(), 0, 12F.dip2px(), 0)
val params = LinearLayout.LayoutParams(LinearLayout.LayoutParams.WRAP_CONTENT, 24F.dip2px())
layoutParams = params
}
}
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
super.onActivityResult(requestCode, resultCode, data)
if (resultCode == Activity.RESULT_OK) {
@ -843,7 +1072,14 @@ class ForumDetailFragment : BaseLazyTabFragment(), IScrollable {
override fun onBackPressed(): Boolean {
NewLogUtils.logForumDetailEnterOrClick("click_forum_detail_return", mBbsId, mBbsType)
return (mFragmentsList[mBinding.fragmentViewPager.currentItem] as ForumArticleAskListFragment).onBackPressed()
val fragment = mFragmentsList[mBinding.fragmentViewPager.currentItem]
return if (fragment is ForumArticleAskListFragment) {
fragment.onBackPressed()
} else if (fragment is WebFragment && fragment.isAdded) {
fragment.onBackPressed()
} else {
super.onBackPressed()
}
}
@Subscribe(threadMode = ThreadMode.MAIN)
@ -877,30 +1113,13 @@ class ForumDetailFragment : BaseLazyTabFragment(), IScrollable {
super.onDarkModeChanged()
updateToolbarStyle(mIsToolbarWhite)
if (::mBinding.isInitialized) {
listOf(
mBinding.allOrderSfv,
mBinding.askOrderSfv,
mBinding.videoOrderSfv
).forEach {
updateOrderView(it)
}
for (i in 0 until mBinding.fragmentTabLayout.tabCount) {
val tab = mBinding.fragmentTabLayout.getTabAt(i)
if (tab != null) {
BaseFragment_TabLayout.updateTabStyle(tab, tab.isSelected)
}
}
}
}
private fun updateOrderView(view: SegmentedFilterView) {
view.run {
setContainerBackground(R.drawable.button_round_f5f5f5.toDrawable(requireContext()))
setIndicatorBackground(R.drawable.bg_game_collection_sfv_indicator.toDrawable(requireContext()))
setTextColor(
R.color.text_subtitle.toColor(requireContext()),
R.color.text_subtitleDesc.toColor(requireContext())
)
mForumSectionAdapter?.let { it.notifyItemRangeChanged(0, it.itemCount) }
}
}
@ -915,10 +1134,12 @@ class ForumDetailFragment : BaseLazyTabFragment(), IScrollable {
companion object {
const val INDEX_ALL = 0
const val INDEX_ESSENCE = 1
const val INDEX_TRENDS = 2
const val INDEX_ASK = 2
const val INDEX_VIDEO = 3
const val TAB_TITLE_ALL = "全部"
const val TAB_TITLE_ESSENCE = "精华"
const val TAB_TRENDS = "专区"
const val TAB_TITLE_ASK = "问答"
const val TAB_TITLE_VIDEO = "视频"
const val EB_SHOW_QUESTION_BUTTON = "EB_SHOW_QUESTION_BUTTON"

View File

@ -27,15 +27,20 @@ import retrofit2.HttpException
class ForumDetailViewModel(application: Application, val bbsId: String) : AndroidViewModel(application) {
private val mApi = RetrofitManager.getInstance().api
private val mNewApi = RetrofitManager.getInstance().newApi
private val mForumDao = AppDatabase.getInstance().forumDao()
var forumDetail = MutableLiveData<Resource<ForumDetailEntity>>()
val answerLiveData = MediatorLiveData<AnswerEntity>()
val statusEntity = MutableLiveData<ApplyModeratorStatusEntity?>()
val sectionListLiveData = MutableLiveData<List<ForumDetailEntity.Section>>()
var selectedSection = ForumDetailEntity.Section("", "全部")
init {
postForumRead()
getForumDetail()
getModeratorsApplyStatus()
getSections()
}
@SuppressLint("CheckResult")
@ -146,6 +151,20 @@ class ForumDetailViewModel(application: Application, val bbsId: String) : Androi
})
}
fun getSections() {
mNewApi.getForumSections(bbsId)
.compose(observableToMain())
.subscribe(object : Response<List<ForumDetailEntity.Section>>() {
override fun onResponse(response: List<ForumDetailEntity.Section>?) {
response?.run {
val sectionList = ArrayList(this)
sectionList.add(0, ForumDetailEntity.Section("", "全部"))
sectionListLiveData.postValue(sectionList)
}
}
})
}
fun convertArticleDetailToAnswer(articleDetailEntity: ArticleDetailEntity): AnswerEntity {
val answerEntity = AnswerEntity()
@ -162,6 +181,7 @@ class ForumDetailViewModel(application: Application, val bbsId: String) : Androi
answerEntity.videos = articleDetailEntity.videos
answerEntity.status = articleDetailEntity.status ?: ""
answerEntity.type = "community_article"
answerEntity.sectionIdList = articleDetailEntity.sectionIdList
return answerEntity
}

View File

@ -0,0 +1,56 @@
package com.gh.gamecenter.forum.detail
import android.content.Context
import android.view.ViewGroup
import android.view.ViewGroup.MarginLayoutParams
import androidx.recyclerview.widget.RecyclerView
import com.gh.gamecenter.R
import com.gh.gamecenter.common.utils.dip2px
import com.gh.gamecenter.common.utils.toBinding
import com.gh.gamecenter.common.utils.toColor
import com.gh.gamecenter.common.utils.toDrawable
import com.gh.gamecenter.databinding.ItemForumSectionBinding
import com.gh.gamecenter.entity.ForumDetailEntity
import com.lightgame.adapter.BaseRecyclerAdapter
class ForumSectionAdapter(context: Context, val viewModel: ForumDetailViewModel, val onClick: () -> Unit) :
BaseRecyclerAdapter<ForumSectionAdapter.ForumSectionItemViewHolder>(context) {
private var mSectionList = listOf<ForumDetailEntity.Section>()
fun submitList(sectionList: List<ForumDetailEntity.Section>) {
mSectionList = sectionList
notifyItemRangeChanged(0, itemCount)
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ForumSectionItemViewHolder =
ForumSectionItemViewHolder(parent.toBinding())
override fun getItemCount(): Int = mSectionList.size
override fun onBindViewHolder(holder: ForumSectionItemViewHolder, position: Int) {
val entity = mSectionList[position]
holder.binding.root.run {
layoutParams = (layoutParams as MarginLayoutParams).apply {
leftMargin = if (position == 0) 16F.dip2px() else 6F.dip2px()
}
text = entity.name
setTextColor(
if (entity.id == viewModel.selectedSection.id) R.color.theme_font.toColor(mContext) else R.color.text_subtitle.toColor(
mContext
)
)
background =
if (entity.id == viewModel.selectedSection.id) R.drawable.button_round_primary_light.toDrawable(mContext) else R.drawable.button_round_gray_light.toDrawable(
mContext
)
setOnClickListener {
viewModel.selectedSection = entity
notifyItemRangeChanged(0, itemCount)
onClick.invoke()
}
}
}
class ForumSectionItemViewHolder(val binding: ItemForumSectionBinding) : RecyclerView.ViewHolder(binding.root)
}

View File

@ -170,6 +170,7 @@ class CommunityHomeFragment : LazyFragment() {
topBg.translationY = 0F
changeNavigationBg()
NewLogUtils.logCommunityHomeEvent("click_for_you_tab")
SensorsBridge.trackEvent("CommunityTopTabSelected", "tab_type", "推荐")
}
TAB_FORUM_INDEX -> {
root.setBackgroundColor(R.color.background_white.toColor(requireContext()))
@ -178,6 +179,7 @@ class CommunityHomeFragment : LazyFragment() {
changeNavigationBg(this)
}
NewLogUtils.logCommunityHomeEvent("click_forum_tab")
SensorsBridge.trackEvent("CommunityTopTabSelected", "tab_type", "论坛")
}
TAB_ACTIVITY_INDEX -> {
root.setBackgroundColor(R.color.background.toColor(requireContext()))
@ -186,6 +188,7 @@ class CommunityHomeFragment : LazyFragment() {
changeNavigationBg(this)
}
NewLogUtils.logCommunityHomeEvent("click_activity_tab")
SensorsBridge.trackEvent("CommunityTopTabSelected", "tab_type", "活动")
}
}
},
@ -407,7 +410,7 @@ class CommunityHomeFragment : LazyFragment() {
MtaHelper.onEvent("论坛首页", "发布", "发帖子")
NewLogUtils.logArticleEditEnter("推荐信息流", "", "")
startActivityForResult(
ArticleEditActivity.getIntent(requireContext(), null),
ArticleEditActivity.getIntent(requireContext(), null, entrance = "社区推荐Tab"),
ARTICLE_REQUEST_CODE
)
dialog.dismiss()
@ -421,7 +424,10 @@ class CommunityHomeFragment : LazyFragment() {
showRegulationTestDialogIfNeeded {
MtaHelper.onEvent("论坛首页", "发布", "提问")
NewLogUtils.logQuestionEditEnter("推荐信息流", "", "")
startActivityForResult(QuestionEditActivity.getIntent(requireContext()), QUESTION_REQUEST_CODE)
startActivityForResult(
QuestionEditActivity.getIntent(requireContext(), entrance = "社区推荐Tab"),
QUESTION_REQUEST_CODE
)
dialog.dismiss()
}
}

View File

@ -209,6 +209,7 @@ class ForumArticleAskItemViewHolder(val binding: CommunityAnswerItemBinding) :
}
binding.concernBtn.setOnClickListener {
debounceActionWithInterval(R.id.concernBtn, 1000) {
SensorsBridge.trackEvent("FollowUserClick", "mongold_id", userId)
CheckLoginUtils.checkLogin(itemView.context, entrance) {
if (entrance == "社区") {
NewLogUtils.logRecommendFeedUserClick("click_for_you_follow", userId, contentType)

View File

@ -2,8 +2,8 @@ package com.gh.gamecenter.forum.search
import android.os.Bundle
import android.view.View
import androidx.appcompat.content.res.AppCompatResources
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat
import com.gh.gamecenter.R
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.databinding.FragmentSearchDefaultBinding
@ -75,11 +75,12 @@ class ForumOrUserSearchDefaultFragment : SearchDefaultFragment() {
headTitle.textSize = 16F
headActionTv.text = "清空"
headActionTv.setTextColor(R.color.text_subtitleDesc.toColor(requireContext()))
headActionTv.setDrawableStart(VectorDrawableCompat.create(
resources,
R.drawable.search_history_delete,
null
))
headActionTv.setDrawableStart(
AppCompatResources.getDrawable(
requireContext(),
R.drawable.search_history_delete
)
)
headActionTv.setOnClickListener {
DialogHelper.showCenterWarningDialog(requireContext(), "清空记录", "确定清空历史搜索记录?", confirmClickCallback = {
mSearchDao.deleteAll()

View File

@ -42,6 +42,8 @@ import com.google.android.material.appbar.AppBarLayout
import com.halo.assistant.fragment.WebFragment
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import org.json.JSONException
import org.json.JSONObject
import kotlin.math.abs
class HomeSearchToolWrapperFragment : SearchToolWrapperFragment() {
@ -158,6 +160,16 @@ class HomeSearchToolWrapperFragment : SearchToolWrapperFragment() {
mViewModel?.tabs?.value?.run {
this.safelyGetInRelease(position).let {
LogUtils.logHomeTopTabClick(it?.name, it?.type, it?.text, it?.link, position)
val trackEvent = JSONObject()
try {
trackEvent.put("position", position)
trackEvent.put("tab_content", it?.name)
} catch (e: JSONException) {
e.printStackTrace()
}
SensorsBridge.trackEvent("HomeTopTabSelect", trackEvent)
if (it?.type == "common_collection") {
NewLogUtils.logAccessToCommonCollectionDetail(it.link ?: "", it.text ?: "", "首页顶部Tab栏")
}

View File

@ -11,6 +11,7 @@ import com.gh.gamecenter.common.utils.singleToMain
import com.gh.gamecenter.common.utils.toColor
import com.gh.gamecenter.entity.HomeDataEntity
import com.gh.gamecenter.entity.SubjectRecommendEntity
import com.gh.gamecenter.pkg.PkgHelper
import com.gh.gamecenter.retrofit.RetrofitManager
import com.halo.assistant.HaloApp
@ -64,6 +65,20 @@ class HomeSearchToolWrapperViewModel(application: Application) : AndroidViewMode
if (homeTab.size == 0) {
homeTab.add(SubjectRecommendEntity(type = "home"))
}
// 从推广包配置信息里找是否需要默认选中一个 tab
PkgHelper.getPkgConfig(true)?.let { pkgLinkEntity ->
if (pkgLinkEntity.shouldStayAtHomePage) {
for ((index, tab) in homeTab.withIndex()) {
if (pkgLinkEntity.type == tab.type
&& (pkgLinkEntity.link == tab.link || tab.link == null)) {
defaultTabPosition = index
break
}
}
}
}
if (!isRefresh) {
tabs.postValue(homeTab)
}

View File

@ -29,22 +29,29 @@ import com.facebook.imagepipeline.image.ImageInfo;
import com.gh.common.constant.Config;
import com.gh.common.dialog.PrivacyPolicyDialogFragment;
import com.gh.common.dialog.ReserveDialog;
import com.gh.common.util.DirectUtils;
import com.gh.common.util.HomeBottomBarHelper;
import com.gh.common.util.IntegralLogHelper;
import com.gh.common.util.LogUtils;
import com.gh.common.util.NewLogUtils;
import com.gh.gamecenter.R;
import com.gh.gamecenter.ShellActivity;
import com.gh.gamecenter.category2.CategoryV2Fragment;
import com.gh.gamecenter.common.base.fragment.BaseFragment_ViewPager_Checkable;
import com.gh.gamecenter.common.callback.BiCallback;
import com.gh.gamecenter.common.callback.OnDoubleTapListener;
import com.gh.gamecenter.common.constant.Constants;
import com.gh.gamecenter.common.constant.EntranceConsts;
import com.gh.gamecenter.common.entity.PkgConfigEntity;
import com.gh.gamecenter.common.eventbus.EBReuse;
import com.gh.gamecenter.common.syncpage.SyncPageRepository;
import com.gh.gamecenter.common.tracker.TrackerLogger;
import com.gh.gamecenter.common.utils.ExtensionsKt;
import com.gh.gamecenter.common.utils.ImageUtils;
import com.gh.gamecenter.common.utils.SensorsBridge;
import com.gh.gamecenter.core.utils.DisplayUtils;
import com.gh.gamecenter.core.utils.GsonUtils;
import com.gh.gamecenter.core.utils.SPUtils;
import com.gh.gamecenter.databinding.FragmentMainBinding;
import com.gh.gamecenter.entity.SubjectData;
import com.gh.gamecenter.entity.SubjectRecommendEntity;
@ -58,9 +65,11 @@ import com.gh.gamecenter.game.GameFragment;
import com.gh.gamecenter.game.columncollection.detail.ColumnCollectionDetailFragment;
import com.gh.gamecenter.game.commoncollection.detail.CommonCollectionDetailFragment;
import com.gh.gamecenter.gamecollection.square.GameCollectionSquareFragment;
import com.gh.gamecenter.login.entity.UserInfoEntity;
import com.gh.gamecenter.message.MessageUnreadRepository;
import com.gh.gamecenter.message.MessageUnreadViewModel;
import com.gh.gamecenter.personal.HaloPersonalFragment;
import com.gh.gamecenter.pkg.PkgHelper;
import com.gh.gamecenter.servers.GameServersPublishFragment;
import com.gh.gamecenter.servers.GameServersTestFragment;
import com.gh.gamecenter.subject.SubjectFragment;
@ -74,6 +83,8 @@ import com.lightgame.view.NoScrollableViewPager;
import org.greenrobot.eventbus.EventBus;
import org.greenrobot.eventbus.Subscribe;
import org.greenrobot.eventbus.ThreadMode;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
@ -263,6 +274,43 @@ public class MainWrapperFragment extends BaseFragment_ViewPager_Checkable implem
.getUnreadMessageTotalLiveData().observe(this, isShow -> ExtensionsKt.goneIf(mBinding.mainIvMessageHint, !isShow));
}
private void applyPkgConfig() {
PkgConfigEntity.PkgLinkEntity pkgLinkEntity = PkgHelper.INSTANCE.getPkgConfig(false);
if (pkgLinkEntity != null) {
String bottomTab = pkgLinkEntity.getHomeBottomTab();
if (!pkgLinkEntity.getShouldStayAtHomePage()) {
// 不停留在首页,执行跳转,标记已用
PkgHelper.INSTANCE.markConfigUsed();
DirectUtils.directToLinkPage(requireContext(), pkgLinkEntity, "推广包配置", "首页");
} else if (!"home".equals(bottomTab)) {
// 停留首页,但选中底部 tab 不是首页的,执行选中,标记已用
PkgHelper.INSTANCE.markConfigUsed();
// TODO 根据具体 tab 来作为跳转的具体位置,避免硬编码
int targetIndex = INDEX_HOME;
switch (bottomTab) {
case "game_lib":
targetIndex = INDEX_GAME;
break;
case "community":
targetIndex = INDEX_BBS;
break;
case "video":
targetIndex = INDEX_VIDEO;
break;
case "gh":
targetIndex = INDEX_PERSONAL;
break;
}
mViewPager.setCurrentItem(targetIndex);
onPageChanged(targetIndex);
changeColor(targetIndex);
}
}
}
public void getDialog() {
mViewModel.requestOpeningData();
mViewModel.getPrivacyPolicyDialog().observe(this, it -> {
@ -346,6 +394,8 @@ public class MainWrapperFragment extends BaseFragment_ViewPager_Checkable implem
}
});
}
applyPkgConfig();
}
@Override
@ -353,9 +403,36 @@ public class MainWrapperFragment extends BaseFragment_ViewPager_Checkable implem
final int toCheck = mCheckableGroup.indexOfChild(view);
playTabAnimation(toCheck);
changeColor(toCheck);
JSONObject trackEvent = new JSONObject();
try {
trackEvent.put("position", toCheck);
trackEvent.put("tab_content", getTabName(toCheck));
} catch (JSONException e) {
e.printStackTrace();
}
SensorsBridge.trackEvent("HomeBottomTabSelect", trackEvent);
return super.handleOnClick(view);
}
private String getTabName(int index) {
switch (index) {
case 0:
return "首页";
case 1:
return mBinding.mainTabGameName.getText().toString();
case 2:
return "社区";
case 3:
return "视频";
case 4:
return "我的光环";
default:
return "";
}
}
private void changeColor(int toCheck) {
if (toCheck == INDEX_VIDEO) {
mBinding.viewShadow.setVisibility(View.GONE);
@ -579,6 +656,33 @@ public class MainWrapperFragment extends BaseFragment_ViewPager_Checkable implem
} else {
mBinding.mainTabCommunity.setVisibility(View.VISIBLE);
}
} else if (Constants.EB_REALNAME_RESULT.equals(reuse.getType())) {
updateRealNameErrorContainer();
}
}
private void updateRealNameErrorContainer() {
String deviceCertificationInfoString =
SPUtils.getString(Constants.SP_DEVICE_CERTIFICATION_PREFIX + HaloApp.getInstance().getGid());
// 未点过关闭按钮并且处于实名认证失败状态的,显示提示 view
if (!SPUtils.getBoolean(Constants.SP_REALNAME_ERROR_HINT_IGNORED)
&& !TextUtils.isEmpty(deviceCertificationInfoString)) {
UserInfoEntity entity = GsonUtils.fromJson(deviceCertificationInfoString, UserInfoEntity.class);
if (entity.getIdCard() != null
&& entity.getIdCard().getStatus() == 2) {
mBinding.realNameErrorContainer.setVisibility(View.VISIBLE);
ExtensionsKt.enlargeTouchArea(mBinding.realNameErrorCloseIv, 100);
mBinding.realNameErrorCloseIv.setOnClickListener(v -> {
SPUtils.setBoolean(Constants.SP_REALNAME_ERROR_HINT_IGNORED, true);
mBinding.realNameErrorContainer.setVisibility(View.GONE);
});
mBinding.realNameErrorContainer.setOnClickListener(v -> {
startActivity(ShellActivity.getIntent(requireActivity(), ShellActivity.Type.REAL_NAME_INFO, null));
});
} else {
mBinding.realNameErrorContainer.setVisibility(View.GONE);
}
}
}

View File

@ -284,7 +284,7 @@ public class SearchToolbarFragment extends BaseLazyFragment implements View.OnCl
MtaHelper.onEvent("首页_点击", "顶栏", "搜索");
DataCollectionUtils.uploadClick(getActivity(), "搜索图标", "主页");
intent = SearchActivity.getIntent(requireContext(), true, mSearchHintTv.getHint().toString(), "(工具栏)");
intent = SearchActivity.getIntent(requireContext(), true, mSearchHintTv.getHint().toString(), "(工具栏)", mLocation);
startActivity(intent);
} else if (id == R.id.actionbar_search_input || id == R.id.actionbar_search_rl || id == R.id.actionbar_search_right) {
MtaHelper.onEvent("首页_点击", "顶栏", "搜索");
@ -293,7 +293,7 @@ public class SearchToolbarFragment extends BaseLazyFragment implements View.OnCl
LogUtils.uploadSearchGame("access_to_search", mLocation, "", "");
}
intent = SearchActivity.getIntent(requireContext(), false, mSearchHintTv.getHint().toString(), "(工具栏)");
intent = SearchActivity.getIntent(requireContext(), false, mSearchHintTv.getHint().toString(), "(工具栏)", mLocation);
startActivity(intent);
} else if (id == R.id.actionbar_notification) {
MtaHelper.onEvent("首页_点击", "顶栏", "消息中心");

View File

@ -12,6 +12,7 @@ import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.entity.CommunityEntity
import com.gh.gamecenter.common.utils.ImageUtils
import com.gh.gamecenter.common.utils.SensorsBridge
import com.gh.gamecenter.common.view.WrapContentDraweeView
import com.gh.gamecenter.core.utils.MtaHelper
import com.gh.gamecenter.core.utils.TimeElapsedHelper
@ -43,6 +44,7 @@ class WelcomeDialogFragment : BaseDialogFragment() {
HaloApp.put(Constants.WELCOME_DIALOG_ID, mWelcomeEntity?.id)
HaloApp.put(Constants.WELCOME_DIALOG_LINK_TITLE, mWelcomeEntity?.text)
LogUtils.uploadWelcomeDialog("click", mWelcomeEntity?.id, mWelcomeEntity?.text)
SensorsBridge.trackEvent("HomeDialogClick")
when (mWelcomeEntity?.type) {
EntranceConsts.HOST_ARTICLE -> {
@ -176,6 +178,7 @@ class WelcomeDialogFragment : BaseDialogFragment() {
arguments = Bundle()
arguments?.putParcelable(TAG, welcomeEntity)
LogUtils.uploadWelcomeDialog("show", welcomeEntity?.id, welcomeEntity?.text)
SensorsBridge.trackEvent("HomeDialogShow")
}
}

View File

@ -11,7 +11,6 @@ import androidx.recyclerview.widget.RecyclerView
import com.ethanhua.skeleton.Skeleton
import com.ethanhua.skeleton.ViewSkeletonScreen
import com.gh.common.exposure.ExposureListener
import com.gh.gamecenter.feature.exposure.ExposureSource
import com.gh.common.util.DialogUtils
import com.gh.common.xapk.XapkInstaller
import com.gh.common.xapk.XapkUnzipStatus
@ -32,8 +31,13 @@ import com.gh.gamecenter.eventbus.EBDiscoverChanged
import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.gh.gamecenter.eventbus.EBPackage
import com.gh.gamecenter.eventbus.EBUISwitch
import com.gh.gamecenter.feature.exposure.ExposureSource
import com.gh.gamecenter.fragment.MainWrapperFragment
import com.gh.gamecenter.game.data.GameItemData
import com.gh.gamecenter.home.test_v2.HomeGameTestV2ViewModel
import com.gh.gamecenter.home.test_v2.HomeItemGameTestV2ViewHolder
import com.gh.gamecenter.home.test_v2.HomeItemGameTestV2ViewHolderWatcher
import com.gh.gamecenter.home.test_v2.addViewHolderWatcher
import com.gh.gamecenter.home.video.ScrollCalculatorHelper
import com.halo.assistant.HaloApp
import com.lightgame.download.DataWatcher
@ -44,6 +48,7 @@ import org.greenrobot.eventbus.ThreadMode
class GameFragment : LazyFragment() {
private lateinit var mViewModel: GameViewModel
private lateinit var mHomeGameTestV2ViewModel: HomeGameTestV2ViewModel
private lateinit var mBinding: FragmentGameBinding
private lateinit var mSkeleton: ViewSkeletonScreen
@ -76,9 +81,13 @@ class GameFragment : LazyFragment() {
)
mViewModel = ViewModelProviders.of(this, factory).get(GameViewModel::class.java)
mViewModel.entrance = mEntrance
//新游开测模块
mHomeGameTestV2ViewModel = viewModelProvider()
mHomeGameTestV2ViewModel.location = "板块"
mHomeGameTestV2ViewModel.blockData = mViewModel.blockData
mViewModel.setHomeGameTestV2DownloadStateUpdateHelper(mHomeGameTestV2ViewModel)
super.onFragmentFirstVisible()
mScrollCalculatorHelper = ScrollCalculatorHelper(mBinding.gameList, R.id.autoVideoView, 0)
mViewModel.loadStatus.observe(this) {
if (it != null) {
@ -120,6 +129,7 @@ class GameFragment : LazyFragment() {
super.initRealView()
mBinding = FragmentGameBinding.bind(mCachedView)
mScrollCalculatorHelper = ScrollCalculatorHelper(mBinding.gameList, R.id.autoVideoView, 0)
mBinding.gameRefresh.setColorSchemeColors(ContextCompat.getColor(requireContext(), R.color.theme))
mLayoutManager = FixLinearLayoutManager(context)
val exposureSourceList = arrayListOf<ExposureSource>().apply {
@ -133,7 +143,15 @@ class GameFragment : LazyFragment() {
)
)
}
mListAdapter = GameFragmentAdapter(requireContext(), mViewModel, exposureSourceList, mLayoutManager)
mListAdapter = GameFragmentAdapter(
requireContext(),
mViewModel,
this,
mHomeGameTestV2ViewModel = mHomeGameTestV2ViewModel,
exposureSourceList,
mLayoutManager,
mScrollCalculatorHelper
)
mBinding.gameList.run {
(itemAnimator as DefaultItemAnimator).supportsChangeAnimations = false
@ -160,6 +178,12 @@ class GameFragment : LazyFragment() {
}
})
//监听新游开测条目可见性变化
mBinding.gameList.addViewHolderWatcher(
HomeItemGameTestV2ViewHolder::class.java,
HomeItemGameTestV2ViewHolderWatcher()
)
mExposureListener = ExposureListener(this, mListAdapter)
mBinding.gameList.addOnScrollListener(mExposureListener)
@ -228,44 +252,31 @@ class GameFragment : LazyFragment() {
}
}
override fun onResume() {
if (::mListAdapter.isInitialized) {
if (isEverPause) mListAdapter.notifyDataSetChanged()
}
super.onResume()
}
private fun pauseVideo() {
if (mScrollCalculatorHelper.currentPosition >= 0) {
mScrollCalculatorHelper.currentPlayer?.resetDetailMask()
mScrollCalculatorHelper.currentPlayer?.onVideoPause()
val currentPosition = mScrollCalculatorHelper.currentPlayer?.getCurrentPosition() ?: 0L
val topVideo =
mViewModel.itemDataList.value?.safelyGetInRelease(mScrollCalculatorHelper.currentPosition)?.attachGame?.linkGame?.topVideo
if (topVideo != null) {
ScrollCalculatorHelper.savePlaySchedule(
MD5Utils.getContentMD5(topVideo.url),
currentPosition
)
val currentPlayer = mScrollCalculatorHelper.currentPlayer
if (currentPlayer != null) {
currentPlayer.resetDetailMask()
currentPlayer.onVideoPause()
val currentPosition = currentPlayer.getCurrentPosition()
val videoUrl = currentPlayer.getUrl()
if (videoUrl.isNotEmpty()) {
ScrollCalculatorHelper.savePlaySchedule(MD5Utils.getContentMD5(videoUrl), currentPosition)
}
}
}
private fun resumeVideo() {
if (mScrollCalculatorHelper.currentPlayer != null) {
val topVideo =
mViewModel.itemDataList.value?.safelyGetInRelease(mScrollCalculatorHelper.currentPosition)?.attachGame?.linkGame?.topVideo
if (topVideo != null) {
val position =
ScrollCalculatorHelper.getPlaySchedule(MD5Utils.getContentMD5(topVideo.url))
val currentPlayer = mScrollCalculatorHelper.currentPlayer
if (currentPlayer != null) {
val videoUrl = currentPlayer.getUrl()
if (videoUrl.isNotEmpty()) {
val position = ScrollCalculatorHelper.getPlaySchedule(MD5Utils.getContentMD5(videoUrl))
//这里必须要延迟操作,否则会白屏
mBaseHandler.postDelayed({
if (position != 0L) {
mScrollCalculatorHelper.currentPlayer?.seekTo(position)
mScrollCalculatorHelper.currentPlayer?.onVideoResume(false)
val topVideoVoiceStatus =
SPUtils.getBoolean(Constants.SP_VIDEO_PLAY_MUTE, true)
val topVideoVoiceStatus = SPUtils.getBoolean(Constants.SP_VIDEO_PLAY_MUTE, true)
if (topVideoVoiceStatus) {
mScrollCalculatorHelper.currentPlayer?.mute()
} else {
@ -283,7 +294,7 @@ class GameFragment : LazyFragment() {
override fun onDestroy() {
super.onDestroy()
if (::mScrollCalculatorHelper.isInitialized) {
mScrollCalculatorHelper.currentPlayer?.release()
mScrollCalculatorHelper.release()
}
}

View File

@ -7,6 +7,7 @@ import android.view.View
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.LinearLayout
import androidx.lifecycle.LifecycleOwner
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.ViewHolder
@ -73,7 +74,14 @@ import com.gh.gamecenter.home.HomeGameItemViewHolder
import com.gh.gamecenter.home.discovercard.DiscoverCardGameAdapter
import com.gh.gamecenter.home.discovercard.HomeDiscoverCardViewHolder
import com.gh.gamecenter.home.gamecollection.HomeGameCollectionViewHolder
import com.gh.gamecenter.home.horizontalslidevideo.HomeHorizontalSlideVideoAdapter
import com.gh.gamecenter.home.horizontalslidevideo.HomeHorizontalSlideVideoListViewHolder
import com.gh.gamecenter.home.test_v2.HomeGameTestV2GameListRvAdapter
import com.gh.gamecenter.home.test_v2.HomeGameTestV2ViewModel
import com.gh.gamecenter.home.test_v2.HomeItemGameTestV2ViewHolder
import com.gh.gamecenter.home.video.ScrollCalculatorHelper
import com.gh.gamecenter.servers.GameServersActivity
import com.gh.gamecenter.servers.gametest2.GameServerTestV2Activity
import com.gh.gamecenter.subject.SubjectActivity
import com.lightgame.adapter.BaseRecyclerAdapter
import com.lightgame.download.DownloadEntity
@ -81,8 +89,11 @@ import com.lightgame.download.DownloadEntity
class GameFragmentAdapter(
context: Context,
model: GameViewModel,
val mBasicExposureSource: List<ExposureSource>,
val layoutManager: LinearLayoutManager?
private val mLifecycleOwner: LifecycleOwner,
private val mHomeGameTestV2ViewModel: HomeGameTestV2ViewModel,
private val mBasicExposureSource: List<ExposureSource>,
private val mLayoutManager: LinearLayoutManager?,
private val mScrollCalculatorHelper: ScrollCalculatorHelper? = null
) : BaseRecyclerAdapter<ViewHolder>(context), IExposable {
private val mViewModel: GameViewModel = model
@ -135,6 +146,8 @@ class GameFragmentAdapter(
if (itemData.attachGame != null) return ItemViewType.GAME_ITEM
if (itemData.lineDivider != null) return ItemViewType.DIVIDER_ITEM
if (itemData.discoverCard != null) return ItemViewType.DISCOVER_CARD
if (itemData.gameTestV2Entity != null) return ItemViewType.COLUMN_TEST_V2
if (itemData.horizontalSlideVideo != null) return ItemViewType.HORIZONTAL_SLIDE_VIDEO
return ItemViewType.LOADING
}
@ -173,6 +186,12 @@ class GameFragmentAdapter(
ItemViewType.GAME_ITEM -> HomeGameItemViewHolder(parent.toBinding())
ItemViewType.DIVIDER_ITEM -> HomeDividerViewHolder(parent.toBinding())
ItemViewType.DISCOVER_CARD -> HomeDiscoverCardViewHolder(parent.toBinding())
ItemViewType.COLUMN_TEST_V2 -> HomeItemGameTestV2ViewHolder(
parent.toBinding(),
mHomeGameTestV2ViewModel,
mLifecycleOwner
)
ItemViewType.HORIZONTAL_SLIDE_VIDEO -> HomeHorizontalSlideVideoListViewHolder(parent.toBinding())
else -> GameItemViewHolder(GameItemBinding.bind(mLayoutInflater.inflate(R.layout.game_item, parent, false)))
}
@ -202,6 +221,8 @@ class GameFragmentAdapter(
is HomeGameItemViewHolder -> bindAttachGame(holder, position)
is HomeDividerViewHolder -> holder.bindView(mItemDataList[position].lineDivider ?: 1F)
is HomeDiscoverCardViewHolder -> bindDiscoverCard(holder, position)
is HomeItemGameTestV2ViewHolder -> bindGameTestV2ViewHolder(holder, position)
is HomeHorizontalSlideVideoListViewHolder -> bindHomeHorizontalSlideVideo(holder, position)
}
}
@ -1122,6 +1143,37 @@ class GameFragmentAdapter(
mViewModel.blockData?.name ?: ""
)
}
"column_test_v2" -> {
//跳转到新游开测页面
val link = column.indexRightTopLink
val text = if (column.indexRightTop == "all") {
"全部"
} else {
"更多"
}
val location = "板块"
//埋点上报
if (text == "全部") {
NewFlatLogUtils.logGameTestV2MoreClick(text, location)
//点击进入[新游开测]详情页面
mContext.startActivity(GameServerTestV2Activity.getIntent(mContext, "新游开测"))
} else {
//点击跳转通用链接
if (link != null) {
val blockData = mViewModel.blockData
DirectUtils.directToLinkPage(mContext, link, "新游开测", "")
NewFlatLogUtils.logGameTestV2MoreClick(
text,
location,
blockId = blockData?.link ?: "",
blockName = blockData?.name ?: "",
linkType = link.type ?: "",
linkId = link.link ?: "",
linkText = link.text ?: ""
)
}
}
}
else -> {
if (column.indexRightTopLink != null) {
val link = column.indexRightTopLink!!
@ -1239,7 +1291,7 @@ class GameFragmentAdapter(
val listExposureEventList = arrayListOf<ExposureEvent>()
val spanCount = 3
val snapHelper = holder.bindView(item.discoverCard!!, "版块", mViewModel.blockData?.name ?: "")
val snapHelper = holder.bindView(item.discoverCard!!, "版块", position, mViewModel.blockData?.name ?: "")
val exposureClosure: (Int) -> Unit = {
val gameList = discoverCard.games
@ -1277,6 +1329,21 @@ class GameFragmentAdapter(
}
private fun bindGameTestV2ViewHolder(holder: HomeItemGameTestV2ViewHolder, position: Int) {
val exposureItemData = mItemDataList.getOrNull(position)
val data = exposureItemData?.gameTestV2Entity ?: return
holder.bindData(data, exposureItemData, mBasicExposureSource, position)
}
private fun bindHomeHorizontalSlideVideo(holder: HomeHorizontalSlideVideoListViewHolder, position: Int) {
val item = mItemDataList[position]
item.horizontalSlideVideo?.run {
holder.bindView(this, "版块内容列表", mBasicExposureSource, mScrollCalculatorHelper) {
item.exposureEventList?.add(it)
}
}
}
override fun getItemCount(): Int {
return if (mItemDataList.size > 0) mItemDataList.size + 1 else mItemDataList.size
}
@ -1290,13 +1357,17 @@ class GameFragmentAdapter(
}
if (getItemViewType(gameAndPosition.position) == ItemViewType.VERTICAL_SLIDE_ITEM
|| getItemViewType(gameAndPosition.position) == ItemViewType.DISCOVER_CARD
|| getItemViewType(gameAndPosition.position) == ItemViewType.COLUMN_TEST_V2
|| getItemViewType(gameAndPosition.position) == ItemViewType.HORIZONTAL_SLIDE_VIDEO
) {
val view = layoutManager?.findViewByPosition(gameAndPosition.position)
val view = mLayoutManager?.findViewByPosition(gameAndPosition.position)
val recyclerView = view?.findViewById<RecyclerView>(R.id.recycler_view)
when (val adapter = recyclerView?.adapter) {
is GameVerticalAdapter -> adapter.notifyItemByDownload(download)
is RankCollectionAdapter -> adapter.notifyItemByDownload(download)
is DiscoverCardGameAdapter -> adapter.notifyItemByDownload(download)
is HomeGameTestV2GameListRvAdapter -> adapter.notifyItemByDownload(download)
is HomeHorizontalSlideVideoAdapter -> adapter.notifyItemByDownload(download)
}
} else {
notifyItemChanged(gameAndPosition.position)
@ -1319,12 +1390,16 @@ class GameFragmentAdapter(
if (getItemViewType(position) == ItemViewType.VERTICAL_SLIDE_ITEM
|| getItemViewType(position) == ItemViewType.RANK_COLLECTION
|| getItemViewType(position) == ItemViewType.DISCOVER_CARD
|| getItemViewType(position) == ItemViewType.COLUMN_TEST_V2
|| getItemViewType(position) == ItemViewType.HORIZONTAL_SLIDE_VIDEO
) {
val view = layoutManager?.findViewByPosition(position)
val view = mLayoutManager?.findViewByPosition(position)
val recyclerView = view?.findViewById<RecyclerView>(R.id.recycler_view)
when (val adapter = recyclerView?.adapter) {
is RankCollectionAdapter -> adapter.notifyChildItem()
is DiscoverCardGameAdapter -> adapter.notifyChildItem(packageName)
is HomeGameTestV2GameListRvAdapter -> adapter.notifyChildItem(packageName)
is HomeHorizontalSlideVideoAdapter -> adapter.notifyChildItem(packageName)
else -> recyclerView?.adapter?.notifyDataSetChanged()
}
} else {
@ -1390,6 +1465,32 @@ class GameFragmentAdapter(
}
continue
}
//新游开测相关条目
val gameTestV2 = mItemDataList[position].gameTestV2Entity
val gameTestV2List = mHomeGameTestV2ViewModel.getDataListLiveData().value
gameTestV2List?.forEach { gameDataWrapper ->
val gameEntity = gameDataWrapper.gameData
if (gameEntity != null) {
for (apkEntity in gameEntity.getApk()) {
if (apkEntity.packageName == packageName) {
positionList.add(GameAndPosition(gameEntity, position))
}
}
}
}
if (gameTestV2 != null) continue
val horizontalSlideVideo = mItemDataList[position].horizontalSlideVideo
if (horizontalSlideVideo != null) {
horizontalSlideVideo.data?.forEach {
for (apkEntity in it.getApk()) {
if (apkEntity.packageName == packageName) {
positionList.add(GameAndPosition(it, position))
}
}
}
continue
}
val image = mItemDataList[position].image
if (image != null) positionList.add(GameAndPosition(image, position))

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