Compare commits

...

181 Commits

Author SHA1 Message Date
e58cc2c405 删除 .gradle/caches/build-cache-1 缓存目录 2023-03-24 10:12:49 +08:00
32de24bb09 delete gradlew clean 2023-03-21 16:20:57 +08:00
481a0b5257 add gradlew clean 2023-03-21 15:56:41 +08:00
dd99610310 测试打包时间 2023-03-21 15:24:55 +08:00
448ded444f 新建minio cache 2023-03-21 14:46:02 +08:00
171f1b8e4e 新建minio cache 2023-03-21 14:17:37 +08:00
449cf76cb2 新建minio cache 2023-03-21 14:04:03 +08:00
f204cf3dda 测试aliyun 内网docker build 2023-03-21 10:17:22 +08:00
aa36af2193 修改镜像为aliyun 地址 2023-03-21 09:50:38 +08:00
e7d15fd874 测试打包时间 2023-03-21 09:33:09 +08:00
3b4d7767ec 复制缓存 2023-03-20 17:59:51 +08:00
2b7faed871 复制缓存 2023-03-20 17:55:44 +08:00
bfbef33054 GIT_SUBMODULE_STRATEGY: recursive 2023-03-20 17:47:48 +08:00
e996eb72a7 开启cache 2023-03-20 17:42:44 +08:00
67a7b7b5ce test 2023-03-20 17:27:38 +08:00
07ad819a50 tar gradle-cache 2023-03-20 17:04:05 +08:00
c965bed2f8 tar gradle-cache 2023-03-20 16:57:20 +08:00
5db36ab0aa tar gradle-cache 2023-03-20 16:35:13 +08:00
c14b06c3b9 tar gradle-cache 2023-03-20 16:33:19 +08:00
4297d5af70 tar gradle-cache 2023-03-20 16:31:56 +08:00
e230e5a7b6 tar gradle-cache 2023-03-20 16:23:29 +08:00
6e0fcef261 tar gradle-cache 2023-03-20 15:54:06 +08:00
c037a2ff91 tar gradle-cache 2023-03-20 15:23:28 +08:00
e7dc16d234 tar gradle-cache 2023-03-20 14:34:19 +08:00
b22edbba69 change Dockerfile path 2023-03-20 14:18:18 +08:00
a953f282ab change Dockerfile path 2023-03-20 14:08:21 +08:00
211bc0cacb change Dockerfile path 2023-03-20 13:56:25 +08:00
798f1fe2fa 注释GIT_STRATEGY: none 2023-03-20 13:50:42 +08:00
d8755eb3bd 注释GIT_STRATEGY: none 2023-03-20 13:50:39 +08:00
b42ef259d4 注释android_build 2023-03-20 13:48:34 +08:00
b6f6007c66 change Dockerfile path 2023-03-20 13:47:54 +08:00
17de6d423d change docker build arg 2023-03-20 11:50:59 +08:00
1386bb727d change artifacts path 2023-03-20 11:04:19 +08:00
2a6bc205df add docker build 2023-03-20 10:37:10 +08:00
38fd0144a5 change images 2023-03-17 15:37:31 +08:00
85ef012911 ci:change docker images 2023-03-03 16:33:12 +08:00
c480a631cd ci:change docker images 2023-03-03 16:18:04 +08:00
bfd1dda9b3 ci:change docker images 2023-03-03 16:08:44 +08:00
ac53235a09 ci: KUBERNETES_CPU_LIMIT: 12 2023-02-27 18:07:39 +08:00
87c9d85b51 change org.gradle.jvmargs 2023-02-27 17:27:47 +08:00
8fd5c669d0 ci: KUBERNETES_CPU_LIMIT: 16 2023-02-27 16:09:31 +08:00
cd1c3052f8 ci:change tags pve-local-runner 2023-02-24 10:13:53 +08:00
80e0163235 fix: plugin 添加内部 nexus 源 2023-02-23 16:27:24 +08:00
9867241e3a ci:add KUBERNETES_CPU_LIMIT 2023-02-23 15:32:06 +08:00
92f4058dfc ci:add KUBERNETES_CPU_LIMIT 2023-02-23 14:59:05 +08:00
4bd414566f ci:change tags offline-test 2023-02-23 14:23:41 +08:00
a472eabf6d ci:change tags local-runner 2023-02-23 14:23:41 +08:00
38f780e514 change org.gradle.jvmargs 2023-02-23 14:23:41 +08:00
dc7cb2abe3 change jvmargs 2023-02-23 14:23:41 +08:00
bfdba625b8 change jvmargs 2023-02-23 14:23:41 +08:00
fe10ef135b ci:change tags pve-local-runner 2023-02-23 14:23:41 +08:00
f600197d89 ci:change tags 2023-02-23 14:23:41 +08:00
8362e7d9da ci:change docker image 2023-02-23 14:23:41 +08:00
d92cae7af8 ci:change docker image 2023-02-23 14:23:41 +08:00
c48b786178 change build.gradle 2023-02-23 14:23:41 +08:00
0818e64fe3 change maven url 2023-02-23 14:23:41 +08:00
5983832aa9 add maven url 2023-02-23 14:23:41 +08:00
c833a53bcc add maven url 2023-02-23 14:23:41 +08:00
ad1b5dada3 change kotlin_version 1.7.1 2023-02-23 14:23:41 +08:00
8cd64dd4bc ci:change docker image 2023-02-23 14:23:41 +08:00
fe37a3bd31 ci:change docker image 2023-02-23 14:23:41 +08:00
f3c33decaf change docker image 2023-02-23 14:23:41 +08:00
2a79755777 优化app的build.gradle 2023-02-23 14:23:41 +08:00
a3601fd25c 优化app的build.gradle 2023-02-23 14:23:41 +08:00
40c55dc66f 优化app的build.gradle 2023-02-23 14:23:41 +08:00
e22c3c06b9 change build.gradle 2023-02-23 14:23:41 +08:00
0f7b5055b4 test cache 2023-02-23 14:23:41 +08:00
15246bbf31 change before_script 2023-02-23 14:23:41 +08:00
92b6f1570a change cache 2023-02-23 14:23:41 +08:00
8c195e01d8 change cache 2023-02-23 14:23:41 +08:00
2a7077efab test cache 2023-02-23 14:23:40 +08:00
b6c1aa2323 test cache 2023-02-23 14:23:40 +08:00
bf3ceec277 修改jvm 2023-02-23 14:23:40 +08:00
48b668cf98 修改jvm 2023-02-23 14:23:40 +08:00
b492002c42 修改jvm 2023-02-23 14:23:40 +08:00
7261b6b512 修改gradle 版本 2023-02-23 14:23:40 +08:00
0c04cc3559 ci修改配置 2023-02-23 14:23:40 +08:00
4cf5102534 ci修改配置 2023-02-23 14:23:40 +08:00
b99353475b ci修改cache 2023-02-23 14:23:40 +08:00
f8b88b1b4e ci修改cache 2023-02-23 14:23:40 +08:00
228c938311 修改jvmargs 2023-02-23 14:23:40 +08:00
48cc6c97f9 ci修改cache 缓存目录 2023-02-23 14:23:40 +08:00
87cc042389 增大jvmargs 2023-02-23 14:23:40 +08:00
ab7a27c84b ci修改cache 缓存目录 2023-02-23 14:23:40 +08:00
708314e680 ci修改cache 缓存目录 2023-02-23 14:23:40 +08:00
59f0265cca ci修改cache 缓存目录 2023-02-23 14:23:40 +08:00
1630d24471 ci添加 build 缓存目录 2023-02-23 14:23:40 +08:00
117da57157 添加.gradle/caches 缓存 2023-02-23 14:23:40 +08:00
5c66937b48 test 2023-02-23 14:23:40 +08:00
c2179a665f 修改jvmargs堆大小 2023-02-23 14:23:40 +08:00
10178a2712 修改tags为online 集群来跑android_build 2023-02-23 14:23:40 +08:00
3ab8b6fc15 ci: 更正邮件镜像 2023-02-23 14:23:40 +08:00
dd8989fd6b ci: 更新 ci 配置文件 2023-02-23 14:23:40 +08:00
9bf4439c5b ci: 更新 ci 编译配置 2023-02-23 14:23:40 +08:00
9fd726d28b ci: 更新 ci 编译配置 2023-02-23 14:23:40 +08:00
fc382c9c98 ci: 更新 ci 编译配置 2023-02-23 14:23:40 +08:00
743339ffb4 ci: 更新 ci 编译配置 2023-02-23 14:23:40 +08:00
0d4dcacae1 ci: 更新 ci 编译配置 2023-02-23 14:23:40 +08:00
9d601e9a39 ci: 更新 ci 编译配置 2023-02-23 14:23:40 +08:00
b8d2826aae ci: 添加 ci 编译配置 2023-02-23 14:23:40 +08:00
0e11b03256 ci: 添加 ci 编译配置 2023-02-23 14:23:40 +08:00
ad1e6ce608 ci: 添加 ci 编译配置 2023-02-23 14:23:40 +08:00
b03cba15d4 ci: 添加 ci 编译配置 2023-02-23 14:23:40 +08:00
41f616b4a5 Merge branch 'fix-arm_build_error' into 'dev-5.21.0'
处理 ARM 处理器的编译问题

See merge request halo/android/assistant-android!736
2023-02-23 12:05:15 +08:00
d966f83b2d fix: 更换 7zip 二进制文件源 2023-02-23 11:54:07 +08:00
2c064f8ac3 chore: room 版本更新到 2.4.3 2023-02-23 11:52:21 +08:00
ca547d9ee3 Revert "fix: 将 andResGuard 移动至 init.gradle 避免 arm 处理器找不到处理文件无法正常编译运行"
This reverts commit 462e407238.
2023-02-23 11:40:56 +08:00
ff5f844a9d Merge branch 'fix_arm_build_error' into 'dev-5.21.0'
处理 ARM 设备的正常编译异常问题

See merge request halo/android/assistant-android!735
2023-02-23 10:54:59 +08:00
462e407238 fix: 将 andResGuard 移动至 init.gradle 避免 arm 处理器找不到处理文件无法正常编译运行 2023-02-23 10:40:11 +08:00
e8f9c9349d Merge branch 'fix-lint_error' into 'dev-5.21.0'
fix: 升级 LiveData 依赖来处理 lint 时误报的 error https://issuetracker.google.com/issues/169249668

See merge request halo/android/assistant-android!734
2023-02-23 10:30:22 +08:00
a931f03f1a fix: 升级 LiveData 依赖来处理 lint 时的误报的 error https://issuetracker.google.com/issues/169249668 2023-02-23 10:20:29 +08:00
f16d67a30f Merge remote-tracking branch 'origin/dev' into dev-5.21.0 2023-02-22 17:20:19 +08:00
f2b6c22235 Merge remote-tracking branch 'origin/release' into dev 2023-02-22 17:16:06 +08:00
38798446f2 Merge branch 'fix-GHZS-1372' into 'dev'
fix: 新增[新游开测]功能-前端详情页部分-0221测试  https://jira.shanqu.cc/browse/GHZS-1372

See merge request halo/android/assistant-android!733
2023-02-22 17:06:56 +08:00
d8817e98c8 fix: 新增[新游开测]功能-前端详情页部分-0221测试 https://jira.shanqu.cc/browse/GHZS-1372 2023-02-22 16:59:59 +08:00
0ef88ecfb7 Merge branch 'fix-GHZS-1372' into 'dev'
fix: 新增[新游开测]功能-前端详情页部分-0221测试 https://jira.shanqu.cc/browse/GHZS-1372

See merge request halo/android/assistant-android!730
2023-02-21 17:33:52 +08:00
a70cf3ffd0 fix: 新增[新游开测]功能-前端详情页部分-0221测试 https://jira.shanqu.cc/browse/GHZS-1372 2023-02-21 17:16:22 +08:00
58685b7c24 Merge remote-tracking branch 'origin/dev' into dev-5.21.0 2023-02-21 15:22:20 +08:00
70f64a755e Merge remote-tracking branch 'origin/release' into dev 2023-02-21 14:50:23 +08:00
5371b5be09 Merge branch 'feature-GHZS-1272' into 'dev-5.21.0'
feat: 游戏专题-双列卡片, 动图加载优化 https://jira.shanqu.cc/browse/GHZS-1272

See merge request halo/android/assistant-android!728
2023-02-20 15:15:40 +08:00
68f58588d1 feat: 游戏专题-双列卡片, 动图加载优化 https://jira.shanqu.cc/browse/GHZS-1272 2023-02-20 15:09:30 +08:00
ccbfc69775 Merge branch 'feature-GHZS-1227' into 'dev-5.21.0'
feat: 畅玩组件下载面板文案修改 https://jira.shanqu.cc/browse/GHZS-1227

See merge request halo/android/assistant-android!726
2023-02-20 14:31:46 +08:00
697c1b20bf feat: 畅玩组件下载面板文案修改 https://jira.shanqu.cc/browse/GHZS-1227 2023-02-20 14:22:58 +08:00
d1aaa4c2b1 Merge branch 'fix-GHZS-1257' into 'dev-5.21.0'
fix:【光环助手】竖屏滑动专题闪烁问题 https://jira.shanqu.cc/browse/GHZS-1257

See merge request halo/android/assistant-android!724
2023-02-20 11:06:01 +08:00
8d58f9baa5 fix:【光环助手】竖屏滑动专题闪烁问题 https://jira.shanqu.cc/browse/GHZS-1257 2023-02-17 16:50:48 +08:00
03cf5b0add Merge branch 'fix-GHZS-1258' into 'dev-5.21.0'
fix:【光环助手】游戏单合集数据显示错乱问题 https://jira.shanqu.cc/browse/GHZS-1258

See merge request halo/android/assistant-android!723
2023-02-17 15:04:57 +08:00
ff843c4e5f fix:【光环助手】游戏单合集数据显示错乱问题 https://jira.shanqu.cc/browse/GHZS-1258 2023-02-17 15:04:57 +08:00
f3033b4439 Merge branch 'feature-GHZS-1266' into 'dev-5.21.0'
fix: 【光环助手】APP启动广告图显示异常 https://jira.shanqu.cc/browse/GHZS-1266

See merge request halo/android/assistant-android!721
2023-02-17 12:04:55 +08:00
ddc3335e01 Merge branch 'fix-GHZS-1127' into 'dev'
fix: 修改新游开测不能上拉下拉加载更多的问题

See merge request halo/android/assistant-android!722
2023-02-17 12:04:44 +08:00
81549c78b3 Merge branch 'feature-GHZS-1261' into 'dev-5.21.0'
feat: 【光环助手】APP在横屏场景下显示优化 https://jira.shanqu.cc/browse/GHZS-1261

See merge request halo/android/assistant-android!720
2023-02-17 12:00:38 +08:00
e2c32d9add fix: 修改新游开测不能上拉下拉加载更多的问题 2023-02-17 11:15:12 +08:00
ac79b6eebb fix: 【光环助手】APP启动广告图显示异常 https://jira.shanqu.cc/browse/GHZS-1266 2023-02-17 10:31:26 +08:00
0ba25aaca9 feat: 【光环助手】APP在横屏场景下显示优化 https://jira.shanqu.cc/browse/GHZS-1261 2023-02-17 10:24:59 +08:00
3526787b92 Merge branch 'fix-GHZS-1256' into 'dev'
fix:【光环助手】开服日历表-详细开服显示问题 https://jira.shanqu.cc/browse/GHZS-1256

See merge request halo/android/assistant-android!719
2023-02-16 17:54:54 +08:00
515298361f Merge branch 'fix-GHZS-1331' into 'dev'
fix: 新增[新游开测]功能-前端详情页部分—0216UI测试 https://jira.shanqu.cc/browse/GHZS-1331

See merge request halo/android/assistant-android!718
2023-02-16 17:33:25 +08:00
67b493b335 fix: 新增[新游开测]功能-前端详情页部分—0216UI测试 https://jira.shanqu.cc/browse/GHZS-1331 2023-02-16 17:30:04 +08:00
5fa10a2c09 chore: 版本更新至 5.21.0 2023-02-16 16:47:37 +08:00
51d5ce265a fix:【光环助手】开服日历表-详细开服显示问题 https://jira.shanqu.cc/browse/GHZS-1256 2023-02-16 16:30:46 +08:00
cda4bb860a Merge branch 'fix-GHZS-1273' into 'dev'
fix: 新增[新游开测]功能-前端详情页部分—0215测试 https://jira.shanqu.cc/browse/GHZS-1273

See merge request halo/android/assistant-android!717
2023-02-16 15:37:26 +08:00
6a4c56a9e2 fix: 新增[新游开测]功能-前端详情页部分—0215测试 https://jira.shanqu.cc/browse/GHZS-1273 2023-02-16 15:37:26 +08:00
3d049bb406 Merge remote-tracking branch 'origin/release' into dev
# Conflicts:
#	dependencies.gradle
2023-02-16 14:28:17 +08:00
fd01515733 Merge branch 'fix-GHZS-1270' into 'dev'
fix: 新增[新游开测]功能-前端详情页部分—0215UI测试 https://jira.shanqu.cc/browse/GHZS-1270

See merge request halo/android/assistant-android!715
2023-02-16 11:12:36 +08:00
a687c8b149 fix: 新增[新游开测]功能-前端详情页部分—0215UI测试 https://jira.shanqu.cc/browse/GHZS-1270 2023-02-16 10:34:19 +08:00
77cb3f92a1 Merge branch 'fix-GHZS-1251' into 'dev'
fix: 新增[图标浮层]功能-0214测试(1) https://jira.shanqu.cc/browse/GHZS-1251

See merge request halo/android/assistant-android!713
2023-02-15 19:30:05 +08:00
5a3db9c78e fix: 新增[图标浮层]功能-0214测试(1) https://jira.shanqu.cc/browse/GHZS-1251 2023-02-15 19:10:00 +08:00
51498b005d Merge branch 'fix-GHZS-1207-2' into 'dev'
fix: 补充消息中心文本高亮 https://jira.shanqu.cc/browse/GHZS-1207

See merge request halo/android/assistant-android!712
2023-02-15 18:43:20 +08:00
ec983f7b2c fix: 补充消息中心文本高亮 https://jira.shanqu.cc/browse/GHZS-1207 2023-02-15 18:38:14 +08:00
745e14a8ce Merge branch 'fix-GHZS-1127' into 'dev'
fix: 修改新游开测列表无法加载更多的问题

See merge request halo/android/assistant-android!710
2023-02-15 18:31:27 +08:00
4939129b21 fix: 修改列表无法加载更多的问题 2023-02-15 14:50:07 +08:00
d85da2b1b5 Merge branch 'feature-GHZS-1127' into 'dev'
feat: 新增[新游开测]功能-前端详情页部分—客户端 https://jira.shanqu.cc/browse/GHZS-1127

See merge request halo/android/assistant-android!708
2023-02-15 11:10:12 +08:00
2c90a909a6 feat: 新增[新游开测]功能-前端详情页部分—客户端 https://jira.shanqu.cc/browse/GHZS-1127 2023-02-15 11:10:11 +08:00
bd86051615 Merge remote-tracking branch 'origin/release' into dev 2023-02-15 10:49:01 +08:00
42250edbbc Merge branch 'fix-GHZS-1251' into 'dev'
fix: 新增[图标浮层]功能-0214测试(3) https://jira.shanqu.cc/browse/GHZS-1251

See merge request halo/android/assistant-android!707
2023-02-14 16:10:24 +08:00
252c933649 fix: 新增[图标浮层]功能-0214测试(3) https://jira.shanqu.cc/browse/GHZS-1251 2023-02-14 16:05:20 +08:00
0998109716 Merge remote-tracking branch 'origin/dev' into dev-5.20.0 2023-02-13 17:38:59 +08:00
bf39be9705 Merge branch 'feature-GHZS-1240' into 'dev-5.20.0'
fix: 新增[图标浮层]功能-0213UI测试 https://jira.shanqu.cc/browse/GHZS-1240

See merge request halo/android/assistant-android!704
2023-02-13 15:38:34 +08:00
20c4ee5c0e fix: 新增[图标浮层]功能-0213UI测试 https://jira.shanqu.cc/browse/GHZS-1240 2023-02-13 14:24:38 +08:00
db119c22b3 Merge branch 'feature-GHZS-1001' into 'dev-5.20.0'
fix: 优化普通帖子详情评论区的显示 https://jira.shanqu.cc/browse/GHZS-1001

See merge request halo/android/assistant-android!699
2023-02-10 15:34:37 +08:00
02ba8df424 fix: 优化普通帖子详情评论区的显示 https://jira.shanqu.cc/browse/GHZS-1001 2023-02-10 15:34:37 +08:00
677f1d6fb9 Merge branch 'feature-GHZS-1100' into 'dev-5.20.0'
feat: 新增[图标浮层]功能—客户端 https://jira.shanqu.cc/browse/GHZS-1100

See merge request halo/android/assistant-android!693
2023-02-10 09:54:37 +08:00
5bf0bb5042 feat: 新增[图标浮层]功能—客户端 https://jira.shanqu.cc/browse/GHZS-1100 2023-02-10 09:54:37 +08:00
8e2fcd08b9 Merge remote-tracking branch 'origin/dev' into dev-5.20.0 2023-02-09 10:33:20 +08:00
b5722e8e06 Merge branch 'feature-GHZS-1103' into 'dev-5.20.0'
fix: 发现页相关功能优化(第二期)—客户端 https://jira.shanqu.cc/browse/GHZS-1103

See merge request halo/android/assistant-android!689
2023-02-08 11:15:15 +08:00
44e331d368 fix: 发现页相关功能优化(第二期)—客户端 https://jira.shanqu.cc/browse/GHZS-1103 2023-02-08 11:12:02 +08:00
562faceba9 Merge branch 'feature-GHZS-1066' into 'dev-5.20.0'
fix:【光环助手】资讯文章-下载按钮显示问题(0206测试1) https://jira.shanqu.cc/browse/GHZS-1066

See merge request halo/android/assistant-android!683
2023-02-06 14:45:24 +08:00
656204de13 fix:【光环助手】资讯文章-下载按钮显示问题(0206测试1) https://jira.shanqu.cc/browse/GHZS-1066 2023-02-06 14:42:54 +08:00
afdf102f85 Merge branch 'feature-GHZS-1119' into 'dev-5.20.0'
fix: 模拟器图片显示优化—客户端 https://jira.shanqu.cc/browse/GHZS-1119

See merge request halo/android/assistant-android!675
2023-02-01 17:48:58 +08:00
3f48d460fb fix: 模拟器图片显示优化—客户端 https://jira.shanqu.cc/browse/GHZS-1119 2023-02-01 17:43:13 +08:00
43db2becf2 Merge branch 'feature-GHZS-1064' into 'dev-5.20.0'
fix:【光环助手】多版本下载面板-版本说明显示问题 https://jira.shanqu.cc/browse/GHZS-1064

See merge request halo/android/assistant-android!674
2023-02-01 16:54:38 +08:00
e3d4aa66f9 fix:【光环助手】多版本下载面板-版本说明显示问题 https://jira.shanqu.cc/browse/GHZS-1064 2023-02-01 16:46:22 +08:00
a7012fa27f Merge branch 'feature-vpn' into 'dev-5.20.0'
feat: 完成简单的 VPN 网络限制功能 https://jira.shanqu.cc/browse/GHZS-1136

See merge request halo/android/assistant-android!673
2023-02-01 15:58:47 +08:00
540982250a feat: 完成简单的 VPN 网络限制功能 https://jira.shanqu.cc/browse/GHZS-1136?jql=text%20~%20%22vpn%22 2023-02-01 15:38:35 +08:00
3a5cddf250 Merge branch 'feature-GHZS-1048' into 'dev-5.20.0'
fix:【光环助手】内容卡片-游戏开服 相关问题 https://jira.shanqu.cc/browse/GHZS-1048

See merge request halo/android/assistant-android!672
2023-02-01 15:26:25 +08:00
48c5171e92 fix:【光环助手】内容卡片-游戏开服 相关问题 https://jira.shanqu.cc/browse/GHZS-1048 2023-02-01 15:23:10 +08:00
3dcc23509f Merge branch 'feature-GHZS-1051' into 'dev-5.20.0'
fix: 【光环助手】游戏单前端显示问题 https://jira.shanqu.cc/browse/GHZS-1051

See merge request halo/android/assistant-android!671
2023-02-01 14:05:17 +08:00
04af2a54dd fix: 【光环助手】游戏单前端显示问题 https://jira.shanqu.cc/browse/GHZS-1051 2023-02-01 14:00:03 +08:00
ec9e225c1a Merge branch 'feature-GHZS-1049' into 'dev-5.20.0'
fix:【光环助手】游戏下载过程中闪烁问题 https://jira.shanqu.cc/browse/GHZS-1049

See merge request halo/android/assistant-android!670
2023-02-01 11:46:18 +08:00
01c2ff29f1 Merge branch 'feature-GHZS-1066' into 'dev-5.20.0'
fix:【光环助手】资讯文章-下载按钮显示问题 https://jira.shanqu.cc/browse/GHZS-1066

See merge request halo/android/assistant-android!669
2023-02-01 11:28:23 +08:00
9ddc4b1de0 chore: 版本更新到 5.20.0 2023-02-01 11:26:50 +08:00
de5420f01d fix:【光环助手】资讯文章-下载按钮显示问题 https://jira.shanqu.cc/browse/GHZS-1066 2023-02-01 11:14:46 +08:00
4a79a35394 fix:【光环助手】游戏下载过程中闪烁问题 https://jira.shanqu.cc/browse/GHZS-1049 2023-02-01 11:12:29 +08:00
189 changed files with 3964 additions and 344 deletions

View File

@ -1,43 +1,43 @@
stages:
- analysis
- sendmail
- android-build
- docker-build
## 代码检查
sonarqube_analysis:
android_build:
tags:
- offline-test
stage: analysis
image: sonarsource/sonar-scanner-cli:latest
dependencies: [] #禁止传递来的artifact
stage: android-build
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:
## 获取项目的一级组和二级组和项目名作为projectKey例如projectKey=platform-backend-eci-monitor
- group=`echo $CI_PROJECT_PATH | sed 's#/#-#g'`
- sonar-scanner
-Dsonar.host.url=http://sonarqube-server.sonarqube:9000/
-Dsonar.login=be43de7264ce4c4766eb0c020373c3e74e6df257
-Dsonar.jacoco.reportPaths=target/jacoco.exec
-Dsonar.projectKey=$group
-Dsonar.projectName=$CI_PROJECT_PATH
-Dsonar.sourceEncoding=UTF-8
-Dsonar.exclusions=**/vendor/**,**/errcode/**
-Dsonar.gitlab.project_id=$CI_PROJECT_ID
-Dsonar.gitlab.commit_sha=$CI_COMMIT_SHA
-Dsonar.gitlab.ref_name=$CI_COMMIT_REF_NAME
-Dsonar.gitlab.ci_merge_request_iid=$CI_MERGE_REQUEST_IID
-Dsonar.gitlab.merge_request_discussion=true
-Dsonar.java.binaries=. # 如果不使用Maven或Gradle进行分析则必须手动提供测试二进制文件
- export GRADLE_USER_HOME=./.gradle
- chmod +x ./gradlew
- ./scripts/jenkins_build.sh -c
- rm -rf ./.gradle/caches/build-cache-1
cache:
paths:
- .gradle
only:
- dev
## 发送简易检测结果报告
send_sonar_report:
- feature-ci
# 构建推送docker镜像
docker-build:
tags:
- offline-test
stage: sendmail
stage: docker-build
variables:
GIT_SUBMODULE_STRATEGY: recursive
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
- imageName=`echo $CI_PROJECT_PATH | sed 's#/#-#g'`
- docker build -t registry.cn-shenzhen.aliyuncs.com/ghzs/$imageName:latest .
- docker push registry.cn-shenzhen.aliyuncs.com/ghzs/$imageName:latest
cache:
paths:
- .gradle
policy: pull
only:
- dev
- feature-ci

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

18
Dockerfile Normal file
View File

@ -0,0 +1,18 @@
FROM openjdk:11-jdk
WORKDIR /project
ARG CI_PROJECT_PATH=default_value
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 wget lib32stdc++6 lib32z1 libncurses5 \
&& rm -rf /var/lib/apt/lists/*
COPY . /project

View File

@ -448,7 +448,7 @@ andResGuard {
"*.gif",
]
sevenzip {
artifact = 'com.tencent.mm:SevenZip:1.2.20'
artifact = 'io.github.leon406:SevenZip:1.2.22.5'
}
}
@ -534,4 +534,4 @@ project.afterEvaluate {
}
}
}
}
}

View File

@ -726,6 +726,10 @@
android:name=".discovery.interestedgame.InterestedGameActivity"
android:screenOrientation="portrait" />
<activity
android:name=".servers.gametest2.GameServerTestV2Activity"
android:screenOrientation="portrait" />
<!-- <activity-->
<!-- android:name="${applicationId}.douyinapi.DouYinEntryActivity"-->

View File

@ -262,7 +262,7 @@ public class BindingAdapters {
public static void setGameIcon(View view, GameEntity gameEntity) {
if (gameEntity != null && view instanceof GameIconView) {
((GameIconView) view).displayGameIcon(gameEntity.getIcon(), gameEntity.getIconSubscript());
((GameIconView) view).displayGameIcon(gameEntity.getIcon(), gameEntity.getIconSubscript(), gameEntity.getIconFloat());
}
}
@ -787,12 +787,21 @@ public class BindingAdapters {
public static void setGameName(NoEllipsizeSpaceTextView view, GameEntity game, boolean isShowPlatform, @Nullable Boolean isShowSuffix) {
if (isShowSuffix == null) isShowSuffix = true; // 默认显示
String gameName;
if (isShowPlatform && game.getApk().size() > 0) {
view.setText(String.format("%s - %s", !isShowSuffix ? game.getNameWithoutSuffix() : game.getName(),
gameName = String.format("%s - %s", !isShowSuffix ? game.getNameWithoutSuffix() : game.getName(),
PlatformUtils.getInstance(view.getContext()).getPlatformName(
game.getApk().get(0).getPlatform())));
game.getApk().get(0).getPlatform()));
if (!gameName.equals((String) view.getTag(R.string.tag_game_name_id))) {
view.setText(gameName);
view.setTag(R.string.tag_game_name_id, gameName);
}
} else {
view.setText(!isShowSuffix ? game.getNameWithoutSuffix() : game.getName());
gameName = !isShowSuffix ? game.getNameWithoutSuffix() : game.getName();
if (gameName != null && !gameName.equals((String) view.getTag(R.string.tag_game_name_id))) {
view.setText(gameName);
view.setTag(R.string.tag_game_name_id, gameName);
}
}
}

View File

@ -19,7 +19,7 @@ import com.halo.assistant.HaloApp
@Database(
entities = [AnswerEntity::class, ArticleEntity::class, NewsEntity::class, HistoryGameEntity::class, MyVideoEntity::class, GamesCollectionEntity::class],
version = 12,
version = 13,
exportSchema = false
)
@TypeConverters(
@ -40,7 +40,8 @@ import com.halo.assistant.HaloApp
MeConverter::class,
SimpleGameListConverter::class,
TagInfoListConverter::class,
ActivityLabelListConverter::class
ActivityLabelListConverter::class,
IconFloatConverter::class
)
abstract class HistoryDatabase : RoomDatabase() {
@ -136,6 +137,12 @@ abstract class HistoryDatabase : RoomDatabase() {
}
}
val MIGRATION_12_13: Migration = object : Migration(12, 13) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("Alter TABLE HistoryGameEntity add iconFloat TEXT")
}
}
val instance by lazy {
Room.databaseBuilder(
HaloApp.getInstance().application,
@ -152,6 +159,7 @@ abstract class HistoryDatabase : RoomDatabase() {
.addMigrations(MIGRATION_9_10)
.addMigrations(MIGRATION_10_11)
.addMigrations(MIGRATION_11_12)
.addMigrations(MIGRATION_12_13)
.build()
}
}

View File

@ -56,6 +56,7 @@ object HistoryHelper {
historyGame.des = ""
historyGame.icon = updateEntity.rawIcon ?: updateEntity.icon
historyGame.iconSubscript = updateEntity.iconSubscript
historyGame.iconFloat = updateEntity.iconFloat
historyGame.name = updateEntity.name
historyGame.tagStyle = updateEntity.tagStyle
return historyGame
@ -70,6 +71,7 @@ object HistoryHelper {
historyGame.des = gameEntity.des
historyGame.icon = gameEntity.rawIcon ?: gameEntity.icon
historyGame.iconSubscript = gameEntity.iconSubscript
historyGame.iconFloat = gameEntity.iconFloat
historyGame.name = gameEntity.name
historyGame.tagStyle = gameEntity.tagStyle
historyGame.tag = gameEntity.getTag()

View File

@ -59,7 +59,7 @@ import com.gh.gamecenter.common.utils.NetworkUtils;
import com.gh.gamecenter.common.view.CustomLinkMovementMethod;
import com.gh.gamecenter.common.view.DrawableView;
import com.gh.gamecenter.common.view.FixLinearLayoutManager;
import com.gh.gamecenter.common.view.LimitHeightLinearLayout;
import com.gh.gamecenter.common.view.MaxHeightLinearLayout;
import com.gh.gamecenter.common.view.MaxHeightNestedScrollView;
import com.gh.gamecenter.common.view.VerticalItemDecoration;
import com.gh.gamecenter.core.AppExecutor;
@ -809,8 +809,8 @@ public class DialogUtils {
((TextView) inflate.findViewById(R.id.imprint_title)).setText(titleName);
View head = LayoutInflater.from(context).inflate(R.layout.imprint_content_item, null);
content.addView(head, LinearLayout.LayoutParams.MATCH_PARENT, DisplayUtils.dip2px(30));
LimitHeightLinearLayout imprintContainer = inflate.findViewById(R.id.imprint_container);
imprintContainer.setLimitHeight((int) (context.getResources().getDisplayMetrics().heightPixels * 0.8));
MaxHeightLinearLayout imprintContainer = inflate.findViewById(R.id.imprint_container);
imprintContainer.setMaxHeight((int) (context.getResources().getDisplayMetrics().heightPixels * 0.8));
ArrayList<ApkEntity> list = gameEntity.getApk();
SettingsEntity settings = Config.getSettings();

View File

@ -67,6 +67,7 @@ import com.gh.gamecenter.qa.video.detail.ForumVideoDetailActivity
import com.gh.gamecenter.retrofit.RetrofitManager
import com.gh.gamecenter.servers.GameServerTestActivity
import com.gh.gamecenter.servers.GameServersActivity
import com.gh.gamecenter.servers.gametest2.GameServerTestV2Activity
import com.gh.gamecenter.setting.SettingBridge
import com.gh.gamecenter.subject.SubjectActivity
import com.gh.gamecenter.tag.TagsActivity
@ -430,6 +431,8 @@ object DirectUtils {
"explore_column" -> context.startActivity(DiscoveryActivity.getIntent(context, entrance))
"column_test_v2" -> context.startActivity(GameServerTestV2Activity.getIntent(context, entrance))
"" -> {
// do nothing
}

View File

@ -204,6 +204,7 @@ public class GameUtils {
gameUpdateEntity.setIcon(gameEntity.getIcon());
gameUpdateEntity.setRawIcon(gameEntity.getRawIcon());
gameUpdateEntity.setIconSubscript(gameEntity.getIconSubscript());
gameUpdateEntity.setIconFloat(gameEntity.getIconFloat());
gameUpdateEntity.setName(gameEntity.getName());
gameUpdateEntity.setPackageName(apkEntity.getPackageName());
gameUpdateEntity.setSize(apkEntity.getSize());

View File

@ -1377,4 +1377,51 @@ object NewFlatLogUtils {
}
log(json, "event", false)
}
//新游开测详情页点击tab
fun logGameTestDetailTabClick(tabName: String) {
val json = json {
"event" to "game_test_detail_tab_click"
"tab_name" to tabName
parseAndPutMeta().invoke(this)
}
log(json, "event", false)
}
//新游开测详情页点击时间轴
fun logGameTestDetailTimelineClick(tabName: String, action: String, gameTestStartType: String) {
val json = json {
"event" to "game_test_detail_timeline_click"
"tab_name" to tabName
"action" to action
"game_test_start_type" to gameTestStartType
parseAndPutMeta().invoke(this)
}
log(json, "event", false)
}
//新游开测详情页点击游戏类型
fun logGameTestDetailGameCategoryClick(tabName: String, gameCategory: String, gameTestStartType: String) {
val json = json {
"event" to "game_test_detail_game_category_click"
"tab_name" to tabName
"game_category" to gameCategory
"game_test_start_type" to gameTestStartType
parseAndPutMeta().invoke(this)
}
log(json, "event", false)
}
//浏览新游开测详情页
fun logGameTestDetailView(tabName: String, interval: Long, gameTestStart: Long, gameTestStartType: String) {
val json = json {
"event" to "game_test_detail_view"
"tab_name" to tabName
"interval" to interval
"game_test_start" to gameTestStart
"game_test_start_type" to gameTestStartType
parseAndPutMeta().invoke(this)
}
log(json, "event", false)
}
}

View File

@ -118,6 +118,7 @@ public class PackageUtils {
updateEntity.setIcon(gameEntity.getIcon());
updateEntity.setRawIcon(gameEntity.getRawIcon());
updateEntity.setIconSubscript(gameEntity.getIconSubscript());
updateEntity.setIconFloat(gameEntity.getIconFloat());
updateEntity.setPackageName(apkEntity.getPackageName());
updateEntity.setSize(apkEntity.getSize());
updateEntity.setVersion(apkEntity.getVersion());
@ -185,6 +186,7 @@ public class PackageUtils {
updateEntity.setIcon(gameEntity.getIcon());
updateEntity.setRawIcon(gameEntity.getRawIcon());
updateEntity.setIconSubscript(gameEntity.getIconSubscript());
updateEntity.setIconFloat(gameEntity.getIconFloat());
updateEntity.setPackageName(apkEntity.getPackageName());
updateEntity.setSize(apkEntity.getSize());
updateEntity.setVersion(apkEntity.getVersion());

View File

@ -326,6 +326,11 @@ 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());
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());
ExtensionsKt.addMetaExtra(downloadEntity, Constants.GAME_ICON_FLOAT_BOTTOM_TEXT, gameEntity.getIconFloat().getBottomText());
}
if (SimulatorGameManager.isSimulatorGame(gameEntity)) {
ExtensionsKt.addMetaExtra(downloadEntity, Constants.SIMULATOR_GAME, apkEntity.getFormat());
ExtensionsKt.addMetaExtra(downloadEntity, Constants.SIMULATOR, GsonUtils.toJson(gameEntity.getSimulator()));

View File

@ -334,10 +334,12 @@ public class MainActivity extends BaseActivity {
SPUtils.setBoolean(Constants.SP_NON_WIFI_TIPS, true);
//重置首页视频播放进度
SPUtils.setString(Constants.SP_HOME_VIDEO_PLAY_RECORD, "");
//第一次进入发现页列表数据强制刷新
SPUtils.setBoolean(Constants.SP_DISCOVER_FORCE_REFRESH, true);
postAttentionVideoRecord();
deleteSimulatorGame();
if (SPUtils.getBoolean(RegionSettingHelper.SP_SETTING_FAILURE)){
if (SPUtils.getBoolean(RegionSettingHelper.SP_SETTING_FAILURE)) {
RegionSettingHelper.getRegionSetting();
}

View File

@ -62,6 +62,7 @@ import com.gh.gamecenter.newsdetail.NewsDetailAdapter;
import com.gh.gamecenter.retrofit.RetrofitManager;
import com.lightgame.download.DataWatcher;
import com.lightgame.download.DownloadEntity;
import com.lightgame.download.DownloadStatus;
import com.lightgame.utils.Utils;
import org.greenrobot.eventbus.Subscribe;
@ -139,6 +140,21 @@ public class NewsDetailActivity extends DownloadToolbarActivity implements OnCli
DetailDownloadUtils.detailInvalidate(getDetailViewHolder());
}
}
} else if (gameEntity != null && gameEntity.getApk().size() > 1) {
if (DownloadStatus.downloading.equals(downloadEntity.getStatus())) {
if (getDetailViewHolder().mDownloadTips.getVisibility() == View.GONE || !getDetailViewHolder().mDownloadTips.isAnimating()) {
getDetailViewHolder().mDownloadTips.setVisibility(View.VISIBLE);
ExtensionsKt.setDownloadTipsAnimation(getDetailViewHolder().mDownloadTips, true);
}
} else if (DownloadStatus.waiting.equals(downloadEntity.getStatus()) || DownloadStatus.done.equals(downloadEntity.getStatus()) ||
DownloadStatus.pause.equals(downloadEntity.getStatus()) || DownloadStatus.timeout.equals(downloadEntity.getStatus()) ||
DownloadStatus.subscribe.equals(downloadEntity.getStatus()) || DownloadStatus.overflow.equals(downloadEntity.getStatus()) ||
DownloadStatus.neterror.equals(downloadEntity.getStatus())) {
getDetailViewHolder().mDownloadTips.setVisibility(View.VISIBLE);
ExtensionsKt.setDownloadTipsAnimation(getDetailViewHolder().mDownloadTips, false);
} else {
getDetailViewHolder().mDownloadTips.setVisibility(View.GONE);
}
}
}
@ -405,6 +421,7 @@ public class NewsDetailActivity extends DownloadToolbarActivity implements OnCli
protected void onDestroy() {
super.onDestroy();
handler.removeCallbacksAndMessages(null);
DownloadManager.getInstance().removeObserver(dataWatcher);
}
@Override
@ -421,7 +438,6 @@ public class NewsDetailActivity extends DownloadToolbarActivity implements OnCli
isSentReport = true;
}
DownloadManager.getInstance().removeObserver(dataWatcher);
}
@Override

View File

@ -32,10 +32,7 @@ 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.runOnIoThread
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.core.utils.EmptyCallback
import com.gh.gamecenter.core.utils.MD5Utils
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.core.utils.*
import com.gh.gamecenter.entity.PrivacyPolicyEntity
import com.gh.gamecenter.feature.utils.PlatformUtils
import com.gh.vspace.VHelper
@ -440,6 +437,10 @@ class SplashScreenActivity : BaseActivity() {
ivImage.setImageResource(mPics[position])
if (position == mPics.size - 1) {
val tvSkip = view.findViewById<TextView>(R.id.splsh_guide_tv_skip)
// 如果屏幕特短,或者是平板的横屏显示,把图片改成按高度显示
if (DisplayUtils.isUltraShortScreen()) {
ivImage.scaleType = ImageView.ScaleType.CENTER_INSIDE
}
tvSkip.setOnClickListener {
if (com.gh.gamecenter.common.BuildConfig.BUILD_TIME != 0L) {
showGitLogDialogIfNeeded()

View File

@ -200,11 +200,11 @@ public class LibaoDetailAdapter extends BaseRecyclerAdapter<ViewHolder> {
ExtensionsKt.setRootBackgroundColor(holder.binding.getRoot(), R.color.background_white);
if (mLibaoEntity.getGame() != null) {
holder.binding.libaodetailGameIcon.displayGameIcon(mLibaoEntity.getGame().getIcon(), mLibaoEntity.getGame().getIconSubscript());
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);
} else {
holder.binding.libaodetailGameIcon.displayGameIcon(mLibaoEntity.getIcon(), null);
holder.binding.libaodetailGameIcon.displayGameIcon(mLibaoEntity.getIcon(), null, mLibaoEntity.getGame().getIconFloat());
}
holder.binding.libaodetailName.setText(mLibaoEntity.getName());
if (TextUtils.isEmpty(mLibaoEntity.getPlatform())) {

View File

@ -291,9 +291,9 @@ public class MessageDetailAdapter extends BaseRecyclerAdapter<ViewHolder> {
}
if (mConcernEntity.getGame() != null) {
viewHolder.binding.newsDigestThumb.displayGameIcon(mConcernEntity.getGame().getIcon(), mConcernEntity.getGame().getIconSubscript());
viewHolder.binding.newsDigestThumb.displayGameIcon(mConcernEntity.getGame().getIcon(), mConcernEntity.getGame().getIconSubscript(), mConcernEntity.getGame().getIconFloat());
} else {
viewHolder.binding.newsDigestThumb.displayGameIcon(mConcernEntity.getGameIcon(), null);
viewHolder.binding.newsDigestThumb.displayGameIcon(mConcernEntity.getGameIcon(), null, mConcernEntity.getGame().getIconFloat());
}
viewHolder.binding.newsDigestTitle.setText(mConcernEntity.getGameName());
NewsUtils.setNewsPublishOn(viewHolder.binding.newsDigestTime, mConcernEntity.getTime());

View File

@ -255,7 +255,7 @@ class AmwayAdapter(
binding.gameIconView.displayGameIcon(
amway.game.rawIcon
?: amway.game.icon, amway.game.iconSubscript
?: amway.game.icon, amway.game.iconSubscript, amway.game.iconFloat
)
amway.game.tag?.let {

View File

@ -268,7 +268,6 @@ class DiscoveryFragment : LazyListFragment<DiscoveryItemData, DiscoveryViewModel
if (index < 0) return@setOnClickListener
mListViewModel.discoveryFeedback(gameEntity.id, popupItem.text.toString(), gameEntity.type ?: "") {
NewFlatLogUtils.logDiscoverPageNotInterest(gameEntity.id, gameEntity.name ?: "")
SPUtils.setBoolean(Constants.SP_DISCOVER_FORCE_REFRESH, true)
mAdapter?.entityList?.removeAt(index)
mAdapter?.notifyItemRemoved(index)
decorView?.removeView(binding.root)

View File

@ -13,9 +13,7 @@ import androidx.fragment.app.viewModels
import com.gh.common.util.NewFlatLogUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.fragment.ToolbarFragment
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.databinding.FragmentInterestedGameBinding
import com.gh.gamecenter.entity.InterestedGameEntity
import com.gh.gamecenter.entity.InterestedGameEntity.TypeTag.Tag
@ -115,7 +113,6 @@ class InterestedGameFragment : ToolbarFragment() {
mViewModel.postResult.observeNonNull(this) {
if (it) {
toast("已根据你的偏好优化推荐机制~")
SPUtils.setBoolean(Constants.SP_DISCOVER_FORCE_REFRESH, true)
EventBus.getDefault().post(EBDiscoverChanged())
requireActivity().setResult(Activity.RESULT_OK)
requireActivity().finish()

View File

@ -17,6 +17,7 @@ import androidx.recyclerview.widget.RecyclerView.ViewHolder;
import com.gh.common.util.DialogUtils;
import com.gh.common.util.PackageInstaller;
import com.gh.common.util.PackageUtils;
import com.gh.gamecenter.common.entity.IconFloat;
import com.gh.gamecenter.feature.utils.PlatformUtils;
import com.gh.gamecenter.feature.view.DownloadButton;
import com.gh.common.xapk.XapkInstaller;
@ -125,7 +126,12 @@ class GameDownloadFragmentAdapter extends BaseRecyclerAdapter<ViewHolder> {
if (!TextUtils.isEmpty(rawIcon)) {
icon = rawIcon;
}
viewHolder.binding.dmItemIvIcon.displayGameIcon(icon, ExtensionsKt.getMetaExtra(downloadEntity, Constants.GAME_ICON_SUBSCRIPT));
IconFloat iconFloat = new IconFloat(
ExtensionsKt.getMetaExtra(downloadEntity, Constants.GAME_ICON_FLOAT_TOP_TEXT),
ExtensionsKt.getMetaExtra(downloadEntity, Constants.GAME_ICON_FLOAT_TOP_COLOR),
ExtensionsKt.getMetaExtra(downloadEntity, Constants.GAME_ICON_FLOAT_BOTTOM_TEXT)
);
viewHolder.binding.dmItemIvIcon.displayGameIcon(icon, ExtensionsKt.getMetaExtra(downloadEntity, Constants.GAME_ICON_SUBSCRIPT), iconFloat);
} else {
ImageUtils.display(viewHolder.binding.dmItemIvIcon.getIconIv(), R.mipmap.logo);
viewHolder.binding.dmItemIvIcon.getIconDecoratorIv().setVisibility(View.GONE);

View File

@ -82,12 +82,13 @@ class NewInstalledGameFragmentAdapter(context: Context, private var mViewModel:
name = gameEntity.name
binding.gameIconView.displayGameIcon(
gameEntity.getRawIconInAdvanced(),
gameEntity.iconSubscript
gameEntity.iconSubscript,
gameEntity.iconFloat
)
binding.gameDes.text = gameEntity.brief
}
if (isSimulatorGame(gameEntity)) {
binding.gameIconView.displayGameIcon(gameEntity.icon, gameEntity.iconSubscript)
binding.gameIconView.displayGameIcon(gameEntity.icon, gameEntity.iconSubscript, gameEntity.iconFloat)
}
binding.gameName.text = name
generateExposureEvent(gameEntity)

View File

@ -168,7 +168,7 @@ class UpdatableGameAdapter(private var mViewModel: UpdatableGameViewModel) :
container.setBackgroundColor(R.color.background_white.toColor(context))
}
iconIv.displayGameIcon(update.rawIcon ?: update.icon, update.iconSubscript)
iconIv.displayGameIcon(update.rawIcon ?: update.icon, update.iconSubscript, update.iconFloat)
val nameText = if (!update.readablePlatform.isNullOrEmpty()) {
update.name + " - " + update.readablePlatform
} else {

View File

@ -586,6 +586,11 @@ class UpdatableGameViewModel(
downloadEntity.addMetaExtra(Constants.GAME_ICON_SUBSCRIPT, update.iconSubscript)
downloadEntity.addMetaExtra(Constants.DOWNLOAD_ID, downloadId)
downloadEntity.addMetaExtra(Constants.APK_MD5, update.md5)
if (update.iconFloat != null) {
downloadEntity.addMetaExtra(Constants.GAME_ICON_FLOAT_TOP_TEXT, update.iconFloat?.upperLeftText)
downloadEntity.addMetaExtra(Constants.GAME_ICON_FLOAT_TOP_COLOR, update.iconFloat?.upperLeftColor)
downloadEntity.addMetaExtra(Constants.GAME_ICON_FLOAT_BOTTOM_TEXT, update.iconFloat?.bottomText)
}
val platform = PlatformUtils.getInstance(getApplication()).getPlatformName(update.platform)
if ("官方版" != platform) {

View File

@ -1,6 +1,7 @@
package com.gh.gamecenter.entity
import android.os.Parcelable
import com.gh.gamecenter.common.entity.IconFloat
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.entity.TagStyleEntity
import com.google.gson.annotations.SerializedName
@ -37,6 +38,8 @@ data class AmwayCommentEntity(
var subtitle: String? = "",
@SerializedName("subtitle_style")
var subtitleStyle: TagStyleEntity? = null,
@SerializedName("icon_float")
var iconFloat: IconFloat? = null,
// 曝光用的位置
var sequence: Int = 0,
@ -54,6 +57,7 @@ data class AmwayCommentEntity(
gameEntity.icon = icon
gameEntity.rawIcon = rawIcon
gameEntity.iconSubscript = iconSubscript
gameEntity.iconFloat = iconFloat
gameEntity.platform = ""
gameEntity.subtitle = subtitle ?: ""

View File

@ -1,6 +1,7 @@
package com.gh.gamecenter.entity
import com.gh.common.util.PackageUtils
import com.gh.gamecenter.common.entity.IconFloat
import com.gh.gamecenter.feature.entity.GameEntity
import com.google.gson.annotations.SerializedName
import com.halo.assistant.HaloApp
@ -12,6 +13,7 @@ data class GameInstall(
var name: String? = "",
var icon: String? = "",
var iconSubScript: String? = "",
var iconFloat: IconFloat? = null,
var isSignByGh: Boolean = false,
var installTime: Long = 0,
var version: String = "",
@ -29,6 +31,7 @@ data class GameInstall(
gameInstall.name = game.name
gameInstall.icon = game.rawIcon ?: game.icon
gameInstall.iconSubScript = game.iconSubscript
gameInstall.iconFloat = game.iconFloat
gameInstall.version = PackageUtils.getVersionNameByPackageName(installedPkgName) ?: "unknown"
gameInstall.packageName = installedPkgName
gameInstall.isSmoothGame = game.isVGame()

View File

@ -0,0 +1,14 @@
package com.gh.gamecenter.entity
import com.google.gson.annotations.SerializedName
data class GameServerTestV2Entity(
val tab: String = "",
val category: String = "",
val action: String = "",
@SerializedName("page_id")
val pageId: String = "",
@SerializedName("time_type")
val timeType: String = "",//"时间轴recent近期新游、today今日新游、future即将开测"
val data: ArrayList<ServerTestEntity.SliceData> = arrayListOf()
)

View File

@ -1,5 +1,6 @@
package com.gh.gamecenter.entity
import com.gh.gamecenter.common.entity.IconFloat
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.feature.entity.*
import com.google.gson.annotations.SerializedName
@ -13,6 +14,8 @@ data class GameUpdateEntity(
var rawIcon: String? = null,
@SerializedName("icon_subscript")
var iconSubscript: String? = "",
@SerializedName("icon_float")
var iconFloat: IconFloat? = null,
@SerializedName("package")
var packageName: String = "",
var size: String? = null,
@ -60,6 +63,7 @@ data class GameUpdateEntity(
gameEntity.icon = icon
gameEntity.rawIcon = rawIcon
gameEntity.iconSubscript = iconSubscript
gameEntity.iconFloat = iconFloat
gameEntity.tagStyle = tagStyle
gameEntity.brief = brief
gameEntity.download = download

View File

@ -68,4 +68,38 @@ data class GamesCollectionEntity(
}
return sb.toString()
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (javaClass != other?.javaClass) return false
other as GamesCollectionEntity
// 这里只对比游戏单id判断是否相同
if (id != other.id) return false
return true
}
override fun hashCode(): Int {
var result = id.hashCode()
result = 31 * result + (tags?.hashCode() ?: 0)
result = 31 * result + (activityTags?.hashCode() ?: 0)
result = 31 * result + (games?.hashCode() ?: 0)
result = 31 * result + title.hashCode()
result = 31 * result + intro.hashCode()
result = 31 * result + cover.hashCode()
result = 31 * result + display.hashCode()
result = 31 * result + stamp.hashCode()
result = 31 * result + (count?.hashCode() ?: 0)
result = 31 * result + (user?.hashCode() ?: 0)
result = 31 * result + (me?.hashCode() ?: 0)
result = 31 * result + orderTag.hashCode()
result = 31 * result + (time?.hashCode() ?: 0)
result = 31 * result + status.hashCode()
result = 31 * result + adIconActive.hashCode()
result = 31 * result + isLocalDraft.hashCode()
return result
}
}

View File

@ -2,6 +2,7 @@ package com.gh.gamecenter.entity
import androidx.room.Entity
import androidx.room.PrimaryKey
import com.gh.gamecenter.common.entity.IconFloat
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.entity.TagStyleEntity
import com.google.gson.annotations.SerializedName
@ -12,6 +13,7 @@ data class HistoryGameEntity(
var id: String = "",
var icon: String? = null,
var iconSubscript: String? = null,
var iconFloat: IconFloat? = null,
var name: String? = null,
var brief: String? = null,
@ -36,6 +38,7 @@ data class HistoryGameEntity(
gameEntity.des = des
gameEntity.rawIcon = icon
gameEntity.iconSubscript = iconSubscript
gameEntity.iconFloat = iconFloat
gameEntity.subtitle = subtitle
gameEntity.subtitleStyle = subtitleStyle
gameEntity.name = name

View File

@ -5,6 +5,7 @@ import android.os.Parcelable
import com.gh.gamecenter.common.annotation.SyncPage
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.entity.CommunityEntity
import com.gh.gamecenter.common.entity.IconFloat
import com.gh.gamecenter.common.syncpage.SyncFieldConstants
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.core.utils.TimeUtils
@ -133,6 +134,8 @@ data class PersonalHistoryEntity(
var rawIcon: String? = null,
@SerializedName("icon_subscript")
var iconSubscript: String? = null,
@SerializedName("icon_float")
var iconFloat: IconFloat? = null,
@SerializedName("played_time")
val playedTime: Long = 0

View File

@ -36,6 +36,8 @@ class ServerTestEntity(
class SliceData(
@SerializedName("start_midnight")
val testTime: Long,
@SerializedName("time_type")
val timeType: String,
@SerializedName("games")
var gameList: ArrayList<GameEntity> = arrayListOf()
)

View File

@ -0,0 +1,19 @@
package com.gh.gamecenter.entity
import com.google.gson.annotations.SerializedName
data class StartPointEntity(
val tab: String,
val category: String,
@SerializedName("start_point")
val startPoint: StartPointIdEntity
)
data class StartPointIdEntity(
@SerializedName("recent_id")
val recentId: String = "",
@SerializedName("today_id")
val todayId: String = "",
@SerializedName("future_id")
val futureId: String = "",
)

View File

@ -342,8 +342,8 @@ class ForumDetailFragment : BaseLazyTabFragment(), IScrollable {
mBinding.forumThumbSmall.displayGameIcon(icon, null)
mBinding.forumThumbBig.displayGameIcon(icon, null)
} else {
mBinding.forumThumbSmall.displayGameIcon(game.getIcon(), game.iconSubscript)
mBinding.forumThumbBig.displayGameIcon(game.getIcon(), game.iconSubscript)
mBinding.forumThumbSmall.displayGameIcon(game.getIcon(), game.iconSubscript, game.iconFloat)
mBinding.forumThumbBig.displayGameIcon(game.getIcon(), game.iconSubscript, game.iconFloat)
}
mBinding.toolbar.setNavigationIcon(if (!mIsDarkModeOn) R.drawable.ic_bar_back else R.drawable.ic_bar_back_light)
mBinding.searchIv.setImageDrawable(

View File

@ -326,7 +326,11 @@ class ForumArticleAskItemViewHolder(val binding: CommunityAnswerItemBinding) :
if (entity.bbs.type == "official_bbs") {
forumIcon?.displayGameIcon(entity.bbs.icon, null)
} else {
forumIcon?.displayGameIcon(entity.bbs.game?.getIcon(), entity.bbs.game?.iconSubscript)
forumIcon?.displayGameIcon(
entity.bbs.game?.getIcon(),
entity.bbs.game?.iconSubscript,
entity.bbs.game?.iconFloat
)
}
forumNameTv.setOnClickListener {

View File

@ -48,7 +48,11 @@ class ForumRecordsAdapter(
if (forumEntity.type == "official_bbs") {
forumIv.displayGameIcon(forumEntity.icon, null)
} else {
forumIv.displayGameIcon(forumEntity.game.getIcon(), forumEntity.game.iconSubscript)
forumIv.displayGameIcon(
forumEntity.game.getIcon(),
forumEntity.game.iconSubscript,
forumEntity.game.iconFloat
)
}
root.setOnClickListener {

View File

@ -55,7 +55,11 @@ class HorizontalForumsAdapter(
if (forumEntity.type == "official_bbs") {
forumIv.displayGameIcon(forumEntity.icon, null)
} else {
forumIv.displayGameIcon(forumEntity.game.getIcon(), forumEntity.game.iconSubscript)
forumIv.displayGameIcon(
forumEntity.game.getIcon(),
forumEntity.game.iconSubscript,
forumEntity.game.iconFloat
)
}
followTv.run {

View File

@ -65,7 +65,11 @@ class ForumListAdapter(
if (forumEntity?.type == "official_bbs") {
forumIcon.displayGameIcon(forumEntity.icon, null)
} else {
forumIcon.displayGameIcon(forumEntity.game.getIcon(), forumEntity.game.iconSubscript)
forumIcon.displayGameIcon(
forumEntity.game.getIcon(),
forumEntity.game.iconSubscript,
forumEntity.game.iconFloat
)
}
topLine.visibility = if (position == 0) View.GONE else View.VISIBLE

View File

@ -10,7 +10,6 @@ import android.widget.TextView
import androidx.core.graphics.ColorUtils
import androidx.fragment.app.Fragment
import androidx.viewpager.widget.ViewPager
import com.gh.gamecenter.feature.exposure.ExposureSource
import com.gh.common.util.DirectUtils
import com.gh.common.util.LogUtils
import com.gh.common.util.NewLogUtils
@ -29,6 +28,7 @@ import com.gh.gamecenter.databinding.TabItemMainBinding
import com.gh.gamecenter.discovery.DiscoveryFragment
import com.gh.gamecenter.entity.SubjectData
import com.gh.gamecenter.entity.SubjectRecommendEntity
import com.gh.gamecenter.feature.exposure.ExposureSource
import com.gh.gamecenter.game.GameFragment
import com.gh.gamecenter.game.columncollection.detail.ColumnCollectionDetailFragment
import com.gh.gamecenter.game.commoncollection.detail.CommonCollectionDetailFragment
@ -36,6 +36,7 @@ import com.gh.gamecenter.gamecollection.square.GameCollectionSquareFragment
import com.gh.gamecenter.home.HomeFragment
import com.gh.gamecenter.servers.GameServersPublishFragment
import com.gh.gamecenter.servers.GameServersTestFragment
import com.gh.gamecenter.servers.gametest2.GameServerTestV2Fragment
import com.gh.gamecenter.subject.SubjectFragment
import com.google.android.material.appbar.AppBarLayout
import com.halo.assistant.fragment.WebFragment
@ -494,15 +495,25 @@ class HomeSearchToolWrapperFragment : SearchToolWrapperFragment() {
putString(EntranceConsts.KEY_ENTRANCE, "首页")
putInt(EntranceConsts.KEY_POSITION, index)
})
"column_test_v2" -> GameServerTestV2Fragment().with(Bundle().apply {
putString(EntranceConsts.KEY_ENTRANCE, "首页")
putInt(EntranceConsts.KEY_POSITION, index)
putParcelable(
EntranceConsts.KEY_EXPOSURE_SOURCE,
ExposureSource("顶部tab", tab.name ?: "")
)
})
"bbs" -> Fragment()
else -> Fragment()
}
fragment.arguments?.putInt(EntranceConsts.KEY_TAB_COUNT, tabList.size)
fragment.arguments?.putBoolean(EntranceConsts.KEY_IS_HOME, true)
fragment.arguments?.putParcelable(
EntranceConsts.KEY_EXPOSURE_SOURCE,
ExposureSource("首页顶部Tab栏", tab.name ?: "")
)
if (fragment.arguments?.getParcelable<ExposureSource>(EntranceConsts.KEY_EXPOSURE_SOURCE) == null) {
fragment.arguments?.putParcelable(
EntranceConsts.KEY_EXPOSURE_SOURCE,
ExposureSource("首页顶部Tab栏", tab.name ?: "")
)
}
fragmentList.add(fragment)
}
return fragmentList

View File

@ -40,7 +40,7 @@ class DoubleCardViewHolder(val binding: GameDoubleCardItemAlBinding) : RecyclerV
positionInOriginSubject: Int
) {
subBinding.run {
poster.display(gameEntity.columnImage)
poster.post { poster.display(gameEntity.columnImage) }
gameName.text = gameEntity.name
brief.text =
if (gameEntity.columnRecommend?.text.isNullOrBlank()) gameEntity.brief

View File

@ -121,7 +121,7 @@ public class SpanCountPagerSnapHelper extends PagerSnapHelper {
int[] out = new int[2];
if (layoutManager.canScrollHorizontally()) {
out[0] = distanceToLeft(targetView, getHorizontalHelper(layoutManager));
if (mAddOffsetToSolveWeirdBug) {
if (mAddOffsetToSolveWeirdBug && out[0] != 0) {
out[0] = mIsScrolledLeft ? out[0] + 1 : out[0] - 1;
}
} else {

View File

@ -812,6 +812,7 @@ class GameCollectionDetailFragment :
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == CommentActivity.REQUEST_CODE && resultCode == Activity.RESULT_OK) {
val commentCount = data?.getIntExtra(CommentActivity.COMMENT_COUNT, 0)
val commentId = data?.getStringExtra(EntranceConsts.KEY_COMMENT_ID)
if (commentCount != 0 && commentCount != null) {
mEntity?.count?.comment = commentCount
mListViewModel.commentCount = commentCount
@ -827,6 +828,11 @@ class GameCollectionDetailFragment :
)
)
}
if (!commentId.isNullOrEmpty()) {
mListViewModel.getSingleCommentDetail(commentId)
} else {
mListViewModel.load(LoadType.REFRESH)
}
}
}

View File

@ -20,6 +20,7 @@ import com.gh.gamecenter.common.syncpage.SyncFieldConstants
import com.gh.gamecenter.common.syncpage.SyncPageRepository
import com.gh.gamecenter.common.utils.observableToMain
import com.gh.gamecenter.common.utils.singleToMain
import com.gh.gamecenter.common.utils.toJson
import com.gh.gamecenter.common.utils.toNewSimpleCount
import com.gh.gamecenter.core.utils.*
import com.gh.gamecenter.entity.CommentEntity
@ -29,6 +30,7 @@ import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.qa.article.detail.CommentItemData
import com.gh.gamecenter.qa.comment.base.BaseCommentViewModel
import com.gh.gamecenter.retrofit.RetrofitManager
import com.google.gson.reflect.TypeToken
import com.halo.assistant.HaloApp
import com.lightgame.utils.Utils
import io.reactivex.Single
@ -42,10 +44,10 @@ import tv.danmaku.ijk.media.exo2.ExoSourceManager
open class GameCollectionDetailViewModel(
application: Application,
var gameCollectionId: String,
gameCollectionId: String,
topCommentId: String = ""
) :
BaseCommentViewModel(application, "", "", "", "", topCommentId) {
BaseCommentViewModel(application, "", "", "", "", gameCollectionId, topCommentId) {
var firstItemInitOverLiveData = MutableLiveData<Boolean>()
var followLiveData = MutableLiveData<Boolean>()
@ -99,6 +101,11 @@ open class GameCollectionDetailViewModel(
map["top_comment_id"] = topCommentId
}
return mApi.getGameCollectionComments(gameCollectionId, page, map)
.map {
mTotal = it.headers().get("total")?.toInt() ?: 0
val type = object : TypeToken<List<CommentEntity>>() {}.type
GsonUtils.gson.fromJson(it.body()?.toJson() ?: "", type)
}
}
override fun mergeResultLiveData() {
@ -355,6 +362,7 @@ open class GameCollectionDetailViewModel(
.compose(observableToMain())
.subscribe(object : Response<ResponseBody>() {
override fun onResponse(response: ResponseBody?) {
mTotal--
hideCommentSuccess()
callback.invoke()
}

View File

@ -3,14 +3,16 @@ package com.gh.gamecenter.gamecollection.tag
import android.content.Context
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.common.utils.dip2px
import com.gh.gamecenter.common.utils.goneIf
import com.gh.gamecenter.R
import com.gh.gamecenter.common.utils.toColor
import com.gh.gamecenter.databinding.*
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.databinding.GameCollectionSelectedTagItemBinding
import com.gh.gamecenter.databinding.GameCollectionTagItemBinding
import com.gh.gamecenter.databinding.ItemGameCollectionSelectedTagBinding
import com.gh.gamecenter.databinding.ItemGameCollectionTagBinding
import com.gh.gamecenter.entity.GameCollectionTagEntity
import com.gh.gamecenter.entity.TagInfoEntity
import com.lightgame.adapter.BaseRecyclerAdapter

View File

@ -1119,7 +1119,9 @@ class GameDetailFragment : ToolbarFragment(), IScrollable {
}
mBodyBinding.gamedetailTvName.isSelected = true
val ranking = mNewGameDetailEntity!!.ranking
if (ranking != null) {
val shouldShowRank =
(ranking != null && (mGameEntity?.iconFloat == null || mGameEntity?.iconFloat?.bottomText.isNullOrEmpty())) || (ranking != null && ranking.no.toInt() <= 10 && mGameEntity?.iconFloat != null && !mGameEntity?.iconFloat?.bottomText.isNullOrEmpty())
if (ranking != null && shouldShowRank) {
mBodyBinding.gameDetailRankLl.visibility = View.VISIBLE
mBodyBinding.gameDetailRankTv.text = "${ranking.columnName}${ranking.no}"
mBodyBinding.gameDetailRankTv.isSelected = true
@ -1134,7 +1136,9 @@ class GameDetailFragment : ToolbarFragment(), IScrollable {
}
}
BindingAdapters.setGame(mBodyBinding.gamedetailIvThumb, mGameEntity)
BindingAdapters.setGame(mBodyBinding.gamedetailIvThumb, mGameEntity?.apply {
if (shouldShowRank && iconFloat != null) iconFloat!!.bottomText = ""
})
BindingAdapters.setGame(mBodyBinding.gamedetailThumbSmall, mGameEntity)
mNewGameDetailEntity?.event?.let {
@ -1268,7 +1272,7 @@ class GameDetailFragment : ToolbarFragment(), IScrollable {
closestIndex = index
}
}
currentItem = closestIndex
setCurrentItem(closestIndex, false)
if (contentCardEntity.server!!.calendar.size > 1) {
startAutoPlay(mServerLooperKey)
}

View File

@ -62,7 +62,11 @@ class MyRatingAdapter(
holder.binding.tvComment.setExpandMaxLines(maxDesLines)
holder.binding.tvComment.setIsExpanded(Int.MAX_VALUE == maxDesLines)
holder.binding.gameIcon.displayGameIcon(rating.game.getRawIconIfExisted(), rating.game.iconSubscript)
holder.binding.gameIcon.displayGameIcon(
rating.game.getRawIconIfExisted(),
rating.game.iconSubscript,
rating.game.iconFloat
)
val m = Pattern.compile(RatingEditActivity.LABEL_REGEX).matcher(rating.content)
if (m.find()) {

View File

@ -5,8 +5,6 @@ import android.view.View
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
import androidx.recyclerview.widget.RecyclerView
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.feature.exposure.ExposureSource
import com.gh.common.util.DirectUtils
import com.gh.common.util.DownloadItemUtils
import com.gh.gamecenter.GameDetailActivity
@ -18,6 +16,8 @@ import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.core.utils.RandomUtils
import com.gh.gamecenter.databinding.HomeGameItemBinding
import com.gh.gamecenter.entity.SubjectEntity
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.feature.exposure.ExposureSource
import com.gh.gamecenter.feature.game.GameItemViewHolder
import com.gh.gamecenter.video.detail.VideoDetailContainerViewModel
import com.shuyu.gsyvideoplayer.builder.GSYVideoOptionBuilder
@ -65,7 +65,7 @@ class HomeGameItemViewHolder(val binding: HomeGameItemBinding) : BaseRecyclerVie
.setShowFullAnimation(false)
.build(holder.binding.autoVideoView)
holder.binding.autoVideoView.updateThumb(topVideo?.poster ?: "")
holder.binding.autoVideoView.setData(game, homeSetting.placeholderColor)
holder.binding.autoVideoView.setParamsData(game, homeSetting.placeholderColor)
holder.binding.autoVideoView.detailBtn?.setOnClickListener {
holder.itemView.performClick()
holder.binding.autoVideoView.uploadVideoStreamingPlaying("点击遮罩", true)

View File

@ -16,7 +16,6 @@ import com.gh.gamecenter.R
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.core.utils.StringUtils
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.databinding.LayoutPopupDiscoveryDislikeBinding
@ -106,7 +105,6 @@ class DiscoverCardGameAdapter(
val index = mList.indexOf(gameEntity)
if (index < 0) return@setOnClickListener
discoveryFeedback(gameEntity.id, popupItem.text.toString(), gameEntity.type ?: "") {
SPUtils.setBoolean(Constants.SP_DISCOVER_FORCE_REFRESH, true)
mList.removeAt(index)
notifyItemRemoved(index)
decorView?.removeView(binding.root)

View File

@ -20,24 +20,21 @@ import com.gh.gamecenter.gamecollection.detail.GameCollectionDetailActivity
import com.gh.gamecenter.gamecollection.square.GameCollectionListItemData
import com.lightgame.adapter.BaseRecyclerAdapter
class HomeGameCollectionAdapter(context: Context, private val entrance: String) :
class HomeGameCollectionAdapter(
context: Context,
private val entrance: String,
var gameCollectionItemDataList: List<GameCollectionListItemData>
) :
BaseRecyclerAdapter<HomeGameCollectionAdapter.HomeGameCollectionCardViewHolder>(context) {
private var mGameCollectionItemDataList = listOf<GameCollectionListItemData>()
fun setGameCollectionList(gameCollectionItemDataList: List<GameCollectionListItemData>) {
mGameCollectionItemDataList = gameCollectionItemDataList
notifyDataSetChanged()
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
HomeGameCollectionCardViewHolder(HomeGameCollectionItemCell(mContext).apply { inflate() })
override fun onBindViewHolder(holder: HomeGameCollectionCardViewHolder, position: Int) {
if (mGameCollectionItemDataList.isNotEmpty()) {
if (gameCollectionItemDataList.isNotEmpty()) {
(holder.itemView as HomeGameCollectionItemCell).bindWhenInflated {
(holder.itemView as HomeGameCollectionItemCell).binding?.run {
holder.bindGameCollectionCard(this, mGameCollectionItemDataList[position], entrance)
holder.bindGameCollectionCard(this, gameCollectionItemDataList[position], entrance)
}
}
}
@ -45,7 +42,7 @@ class HomeGameCollectionAdapter(context: Context, private val entrance: String)
override fun getItemViewType(position: Int) = position
override fun getItemCount() = mGameCollectionItemDataList.size
override fun getItemCount() = gameCollectionItemDataList.size
class HomeGameCollectionItemCell(context: Context) : AsyncCell(context) {
var binding: HomeGameCollectionCardItemBinding? = null

View File

@ -22,10 +22,16 @@ class HomeGameCollectionViewHolder(val binding: HomeGameCollectionItemBinding) :
private val mSlideLooperKey = 222
fun bindGameCollectionList(gameCollectionItemDataList: List<GameCollectionListItemData>, entrance: String) {
if (binding.recyclerView.adapter is HomeGameCollectionAdapter) {
if (gameCollectionItemDataList == mAdapter?.gameCollectionItemDataList) {
return
} else if (binding.recyclerView.adapter is HomeGameCollectionAdapter) {
mAdapter?.gameCollectionItemDataList = gameCollectionItemDataList
mAdapter?.notifyDataSetChanged()
binding.recyclerView.scrollToPosition(0)
startAutoPlay()
return
}
mAdapter = HomeGameCollectionAdapter(binding.root.context, entrance)
mAdapter = HomeGameCollectionAdapter(binding.root.context, entrance, gameCollectionItemDataList)
mLayoutManager = StackLayoutManager(
StackLayoutManager.ScrollOrientation.RIGHT_TO_LEFT,
3,
@ -57,7 +63,6 @@ class HomeGameCollectionViewHolder(val binding: HomeGameCollectionItemBinding) :
}
})
}
mAdapter?.setGameCollectionList(gameCollectionItemDataList)
startAutoPlay()
}

View File

@ -13,19 +13,21 @@ import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat
import com.facebook.drawee.view.SimpleDraweeView
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.core.runOnIoThread
import com.gh.gamecenter.core.runOnUiThread
import com.gh.common.util.*
import com.gh.gamecenter.common.view.DrawableView
import com.gh.gamecenter.common.view.RadiusCardView
import com.gh.common.util.LogUtils
import com.gh.download.cache.ExoCacheManager
import com.gh.gamecenter.R
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.utils.ImageUtils
import com.gh.gamecenter.common.utils.countDownTimer
import com.gh.gamecenter.common.utils.dip2px
import com.gh.gamecenter.common.utils.rxTimer
import com.gh.gamecenter.core.utils.*
import com.gh.gamecenter.common.view.DrawableView
import com.gh.gamecenter.common.view.RadiusCardView
import com.gh.gamecenter.core.runOnIoThread
import com.gh.gamecenter.core.runOnUiThread
import com.gh.gamecenter.core.utils.RandomUtils
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.core.utils.doOnEnd
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.video.detail.CustomManager
import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer
@ -41,25 +43,34 @@ class AutomaticVideoView @JvmOverloads constructor(context: Context, attrs: Attr
private var mMuteDisposable: Disposable? = null
private var mMaskDisposable: Disposable? = null
private val mUUID = UUID.randomUUID().toString()
private var shouldShowMask = true
private var mShouldShowMask = true
private var mContentLength = 0.0
private var gameEntity: GameEntity? = null
private var placeholderColor: String? = null
private var mGameEntity: GameEntity? = null
private var mPlaceholderColor: String? = null
private var mClickListener: OnClickListener? = null
private var randomPlaceholderColor = 0
private var mRandomPlaceholderColor = 0
private var mVideoViewRadius = 6F
private var mIsBottomRightAngle = true
init {
val array = context.obtainStyledAttributes(attrs, R.styleable.AutomaticVideoView)
mVideoViewRadius = array.getFloat(R.styleable.AutomaticVideoView_avRadius, 6F)
mIsBottomRightAngle = array.getBoolean(R.styleable.AutomaticVideoView_avBottomRightAngle, true)
array.recycle()
}
override fun getLayoutId(): Int {
return R.layout.empty_control_video
}
fun setData(entity: GameEntity?, color: String?) {
gameEntity = entity
placeholderColor = color
fun setParamsData(entity: GameEntity?, color: String?) {
mGameEntity = entity
mPlaceholderColor = color
setPlaceholderColor(mThumbImageViewLayout, false)
}
fun startPlayLogic(showMask: Boolean) {
shouldShowMask = showMask
mShouldShowMask = showMask
startPlayLogic()
}
@ -111,7 +122,12 @@ class AutomaticVideoView @JvmOverloads constructor(context: Context, attrs: Attr
mMaskDisposable = countDownTimer(5) { finish, _ ->
if (finish) {
val offset = 44f.dip2px().toFloat()
containerView.setRadius(6f, 6f, 0f, 0f)
containerView.setRadius(
mVideoViewRadius,
mVideoViewRadius,
if (mIsBottomRightAngle) 0F else mVideoViewRadius,
if (mIsBottomRightAngle) 0F else mVideoViewRadius
)
detailBtn?.let { mask ->
var params = mask.layoutParams as ConstraintLayout.LayoutParams
@ -119,14 +135,14 @@ class AutomaticVideoView @JvmOverloads constructor(context: Context, attrs: Attr
mask.layoutParams = params
mask.alpha = 0f
mask.visibility = VISIBLE
val heightAnimator = ValueAnimator.ofFloat(0f, offset).apply {
val heightAnimator = ValueAnimator.ofFloat(0F, offset).apply {
addUpdateListener {
params = mask.layoutParams as ConstraintLayout.LayoutParams
params.height = (it.animatedValue as Float).toInt()
mask.layoutParams = params
}
}
val alphaAnimator = ValueAnimator.ofFloat(0f, 1F).apply {
val alphaAnimator = ValueAnimator.ofFloat(0F, 1F).apply {
addUpdateListener {
mask.alpha = it.animatedValue as Float
}
@ -144,19 +160,25 @@ class AutomaticVideoView @JvmOverloads constructor(context: Context, attrs: Attr
}
private fun setPlaceholderColor(view: View?, isOnlyTop: Boolean = true) {
if (!placeholderColor.isNullOrEmpty()) {
if (!mPlaceholderColor.isNullOrEmpty()) {
try {
//去掉透明度
val color = if (placeholderColor!!.length == 9) {
"#${placeholderColor!!.substring(3)}"
val color = if (mPlaceholderColor!!.length == 9) {
"#${mPlaceholderColor!!.substring(3)}"
} else {
placeholderColor
mPlaceholderColor
}
if (color!!.length < 7) {
setRandomBackground(view, isOnlyTop)
} else {
val topRadius = if (isOnlyTop) 0f else 6f
val drawable = DrawableView.getCornerDrawable(Color.parseColor(color), topRadius, topRadius, 6f, 6f)
val topRadius = if (isOnlyTop) 0F else mVideoViewRadius
val drawable = DrawableView.getCornerDrawable(
Color.parseColor(color),
topRadius,
topRadius,
mVideoViewRadius,
mVideoViewRadius
)
view?.background = drawable
}
} catch (e: Exception) {
@ -168,23 +190,23 @@ class AutomaticVideoView @JvmOverloads constructor(context: Context, attrs: Attr
}
private fun setRandomBackground(view: View?, isOnlyTop: Boolean = true) {
if (randomPlaceholderColor == 0) {
randomPlaceholderColor = RandomUtils.getRandomPlaceholderColor()
if (mRandomPlaceholderColor == 0) {
mRandomPlaceholderColor = RandomUtils.getRandomPlaceholderColor()
}
val topRadius = if (isOnlyTop) 0f else 6f
val topRadius = if (isOnlyTop) 0F else mVideoViewRadius
val drawable = DrawableView.getCornerDrawable(
ContextCompat.getColor(context, randomPlaceholderColor),
ContextCompat.getColor(context, mRandomPlaceholderColor),
topRadius,
topRadius,
6f,
6f
mVideoViewRadius,
mVideoViewRadius
)
view?.background = drawable
}
fun resetDetailMask() {
detailBtn?.visibility = View.GONE
containerView.setRadius(6f, 6f, 6f, 6f)
containerView.setRadius(mVideoViewRadius, mVideoViewRadius, mVideoViewRadius, mVideoViewRadius)
if (mMaskDisposable != null && !mMaskDisposable!!.isDisposed) {
mMaskDisposable?.dispose()
mMaskDisposable = null
@ -221,9 +243,9 @@ class AutomaticVideoView @JvmOverloads constructor(context: Context, attrs: Attr
super.onSurfaceUpdated(surface)
if (mThumbImageViewLayout != null && mThumbImageViewLayout.visibility == View.VISIBLE) {
mThumbImageViewLayout.visibility = View.INVISIBLE
if (shouldShowMask) {
if (mShouldShowMask) {
showDetailMask()
shouldShowMask = true
mShouldShowMask = true
}
uploadVideoStreamingPlaying("开始播放")
}
@ -280,8 +302,8 @@ class AutomaticVideoView @JvmOverloads constructor(context: Context, attrs: Attr
}
fun uploadVideoStreamingPlaying(action: String, hasDetailMask: Boolean? = null) {
if (gameEntity == null) return
val topVideo = gameEntity?.topVideo
if (mGameEntity == null) return
val topVideo = mGameEntity?.topVideo
if (topVideo == null || topVideo.url.isEmpty()) return
runOnIoThread(isHeavyWightTask = true) {
val videoPlayTs = currentPositionWhenPlaying / 1000
@ -296,7 +318,7 @@ class AutomaticVideoView @JvmOverloads constructor(context: Context, attrs: Attr
LogUtils.uploadHomeVideoStreamingPlaying(
action, hasDetailMask
?: (detailBtn?.visibility == View.VISIBLE), topVideo.id, topVideo.title,
gameEntity?.id, gameEntity?.name, mContentLength, videoTotalTime, videoPlayTs, progress.toInt()
mGameEntity?.id, mGameEntity?.name, mContentLength, videoTotalTime, videoPlayTs, progress.toInt()
)
}
}

View File

@ -51,6 +51,17 @@ class ScrollCalculatorHelper(private val mListRv: RecyclerView, private val mPla
}
}
fun release() {
if (currentPlayer != null) {
val currentScheduler = currentPlayer?.currentPositionWhenPlaying?.toLong() ?: 0L
savePlaySchedule(MD5Utils.getContentMD5(currentPlayer?.getUrl()), currentScheduler)
CustomManager.releaseAllVideos(currentPlayer?.getKey())
currentPlayer?.resetDetailMask()
currentPlayer = null
currentPosition = -1
}
}
private fun playVideo(view: RecyclerView?) {
if (view == null) return
val layoutManager = view.layoutManager

View File

@ -362,9 +362,9 @@ class ConcernAdapter extends BaseRecyclerAdapter<ViewHolder> {
viewHolder.setClickData(concernEntity);
if (concernEntity.getGame() != null) {
viewHolder.binding.newsDigestThumb.displayGameIcon(concernEntity.getGame().getIcon(), concernEntity.getGame().getIconSubscript());
viewHolder.binding.newsDigestThumb.displayGameIcon(concernEntity.getGame().getIcon(), concernEntity.getGame().getIconSubscript(), concernEntity.getGame().getIconFloat());
} else {
viewHolder.binding.newsDigestThumb.displayGameIcon(concernEntity.getGameIcon(), null);
viewHolder.binding.newsDigestThumb.displayGameIcon(concernEntity.getGameIcon(), null, concernEntity.getGame().getIconFloat());
}
viewHolder.binding.newsDigestTitle.setText(concernEntity.getGameName());

View File

@ -207,7 +207,7 @@ class Libao2FragmentAdapter extends BaseRecyclerAdapter<ViewHolder> {
holder.setClickData(libaoEntity);
ExtensionsKt.setRootBackgroundColor(holder.binding.getRoot(), R.color.background_white);
holder.binding.libaoName.setText(libaoEntity.getName());
holder.binding.libaoGameIcon.displayGameIcon(libaoEntity.getIcon(), libaoEntity.getIconSubscript());
holder.binding.libaoGameIcon.displayGameIcon(libaoEntity.getIcon(), libaoEntity.getIconSubscript(), libaoEntity.getGame().getIconFloat());
if (TextUtils.isEmpty(libaoEntity.getPlatform())) {
holder.binding.libaoGameName.setText(libaoEntity.getGame().getName());
} else {

View File

@ -205,7 +205,7 @@ class Libao3FragmentAdapter extends BaseRecyclerAdapter<RecyclerView.ViewHolder>
final LibaoEntity libaoEntity = mLibaoList.get(position);
ExtensionsKt.setRootBackgroundColor(holder.binding.getRoot(), R.color.background_white);
holder.binding.libaoName.setText(libaoEntity.getName());
holder.binding.libaoGameIcon.displayGameIcon(libaoEntity.getIcon(), libaoEntity.getIconSubscript());
holder.binding.libaoGameIcon.displayGameIcon(libaoEntity.getIcon(), libaoEntity.getIconSubscript(), libaoEntity.getGame().getIconFloat());
if (mFilter.equals("expires:false") && libaoEntity.getExpires() > 0) {
holder.binding.expiresTime.setVisibility(View.VISIBLE);
holder.binding.expiresTime.setText(String.format(Locale.CHINA, "%s过期", TimeUtils.getFormatTime(libaoEntity.getExpires(), "MM.dd")));

View File

@ -161,7 +161,7 @@ public class LibaoHistoryAdapter extends BaseRecyclerAdapter<ViewHolder> {
viewHolder.binding.libaoName.setText(libaoEntity.getName());
viewHolder.binding.libaoDes.setText(libaoEntity.getContent());
viewHolder.binding.libaoGameName.setText(libaoEntity.getGame().getName());
viewHolder.binding.libaoGameIcon.displayGameIcon(libaoEntity.getIcon(), libaoEntity.getIconSubscript());
viewHolder.binding.libaoGameIcon.displayGameIcon(libaoEntity.getIcon(), libaoEntity.getIconSubscript(), libaoEntity.getGame().getIconFloat());
//领取状态
if (TextUtils.isEmpty(libaoEntity.getStatus())) {

View File

@ -201,7 +201,11 @@ class LibaoNewAdapter(
.getPlatformName(libaoEntity.platform)
)
}
holder.binding.libaoGameIcon.displayGameIcon(libaoEntity.getIcon(), libaoEntity.getIconSubscript())
holder.binding.libaoGameIcon.displayGameIcon(
libaoEntity.getIcon(),
libaoEntity.getIconSubscript(),
libaoEntity.game?.iconFloat
)
val content: String
if (libaoEntity.content!!.contains("<br/>")) {

View File

@ -222,7 +222,11 @@ class LibaoSearchAdapter(
.getPlatformName(libaoEntity.platform)
)
}
holder.binding.libaoGameIcon.displayGameIcon(libaoEntity.getIcon(), libaoEntity.getIconSubscript())
holder.binding.libaoGameIcon.displayGameIcon(
libaoEntity.getIcon(),
libaoEntity.getIconSubscript(),
libaoEntity.game?.iconFloat
)
val content: String
if (libaoEntity.content!!.contains("<br/>")) {

View File

@ -107,11 +107,12 @@ public class MessageItemViewHolder extends BaseRecyclerViewHolder<MessageEntity>
List<MessageEntity.Video> videos;
String targetUrl = null; // 防止串行
String imageCommentStr = "[图片评论]";
String content = "";
switch (messageEntity.getType()) {
case "answer":
mBinding.messageCommand.setText("回答了你的问题");
mBinding.messageContent.setVisibility(View.VISIBLE);
mBinding.messageContent.setText(messageEntity.getAnswer().getContent());
content = messageEntity.getAnswer().getContent();
mBinding.messageOriginalTitle.setText(messageEntity.getQuestion().getTitle());
videos = messageEntity.getQuestion().getVideos();
if (videos.size() > 0) {
@ -131,7 +132,7 @@ public class MessageItemViewHolder extends BaseRecyclerViewHolder<MessageEntity>
case "reply":
mBinding.messageCommand.setText("回复了你");
mBinding.messageContent.setVisibility(View.VISIBLE);
mBinding.messageContent.setText(messageEntity.getDialogue().getFrom().getContent());
content = messageEntity.getDialogue().getFrom().getContent();
mBinding.messageOriginalTitle.setText(messageEntity.getDialogue().getTo().getContent());
targetUrl = messageEntity.getArticle().getThumb();
if (TextUtils.isEmpty(targetUrl)) {
@ -145,7 +146,7 @@ public class MessageItemViewHolder extends BaseRecyclerViewHolder<MessageEntity>
case "follow_question":
mBinding.messageCommand.setText("回答了你关注的问题");
mBinding.messageContent.setVisibility(View.VISIBLE);
mBinding.messageContent.setText(messageEntity.getAnswer().getContent());
content = messageEntity.getAnswer().getContent();
mBinding.messageOriginalTitle.setText(messageEntity.getQuestion().getTitle());
images = messageEntity.getAnswer().getImages();
if (images.size() > 0) {
@ -159,7 +160,7 @@ public class MessageItemViewHolder extends BaseRecyclerViewHolder<MessageEntity>
case "reply_answer_comment":
mBinding.messageCommand.setText("回复了你");
mBinding.messageContent.setVisibility(View.VISIBLE);
mBinding.messageContent.setText(messageEntity.getDialogue().getFrom().getContent());
content = messageEntity.getDialogue().getFrom().getContent();
mBinding.messageOriginalTitle.setText(messageEntity.getDialogue().getTo().getContent());
mBinding.messageOriginalIcon.setVisibility(View.GONE);
voteMoreUser(messageEntity);
@ -167,7 +168,7 @@ public class MessageItemViewHolder extends BaseRecyclerViewHolder<MessageEntity>
case "answer_comment":
mBinding.messageCommand.setText("回复了你的回答");
mBinding.messageContent.setVisibility(View.VISIBLE);
mBinding.messageContent.setText(messageEntity.getComment().getContent());
content = messageEntity.getComment().getContent();
if (messageEntity.getAnswer().getContent() != null) {
mBinding.messageOriginalTitle.setText(messageEntity.getAnswer().getContent().replace(imageCommentStr, ""));
}
@ -291,7 +292,7 @@ public class MessageItemViewHolder extends BaseRecyclerViewHolder<MessageEntity>
case "community_article_comment":
mBinding.messageCommand.setText("评论了你的帖子");
mBinding.messageContent.setVisibility(View.VISIBLE);
mBinding.messageContent.setText(messageEntity.getComment().getContent());
content = messageEntity.getComment().getContent();
mBinding.messageOriginalTitle.setText(messageEntity.getArticle().getTitle());
videos = messageEntity.getArticle().getVideos();
if (videos.size() > 0) {
@ -339,7 +340,7 @@ public class MessageItemViewHolder extends BaseRecyclerViewHolder<MessageEntity>
}
}
mBinding.messageContent.setVisibility(View.VISIBLE);
mBinding.messageContent.setText(messageEntity.getDialogue().getFrom().getContent());
content = messageEntity.getDialogue().getFrom().getContent();
if (messageEntity.getDialogue().getTo().getContent() != null) {
mBinding.messageOriginalTitle.setText(messageEntity.getDialogue().getTo().getContent().replace(imageCommentStr, ""));
}
@ -348,7 +349,7 @@ public class MessageItemViewHolder extends BaseRecyclerViewHolder<MessageEntity>
case "update-answer":
mBinding.messageCommand.setText("更新了回答");
mBinding.messageContent.setVisibility(View.VISIBLE);
mBinding.messageContent.setText(messageEntity.getAnswer().getContent());
content = messageEntity.getAnswer().getContent();
mBinding.messageOriginalTitle.setText(messageEntity.getQuestion().getTitle());
images = messageEntity.getAnswer().getImages();
if (images.size() > 0) {
@ -375,7 +376,7 @@ public class MessageItemViewHolder extends BaseRecyclerViewHolder<MessageEntity>
case "game_comment_reply":
mBinding.messageCommand.setText("回复了你的评价");
mBinding.messageContent.setVisibility(View.VISIBLE);
mBinding.messageContent.setText(messageEntity.getReply().getContent());
content = messageEntity.getReply().getContent();
String parentId = messageEntity.getReply().getParent().getId();
// parentContent为空代表是回复评价中的回复否则是回复游戏评价
if (!TextUtils.isEmpty(parentId)) {
@ -420,7 +421,7 @@ public class MessageItemViewHolder extends BaseRecyclerViewHolder<MessageEntity>
case "video_comment":
mBinding.messageCommand.setText("评论了你的帖子");
mBinding.messageContent.setVisibility(View.VISIBLE);
mBinding.messageContent.setText(messageEntity.getComment().getContent());
content = messageEntity.getComment().getContent();
mBinding.messageOriginalTitle.setText(messageEntity.getVideo().getTitle());
targetUrl = messageEntity.getVideo().getPoster();
if (TextUtils.isEmpty(targetUrl)) {
@ -447,7 +448,7 @@ public class MessageItemViewHolder extends BaseRecyclerViewHolder<MessageEntity>
case "reply_activity_comment":
mBinding.messageCommand.setText("回复了你");
mBinding.messageContent.setVisibility(View.VISIBLE);
mBinding.messageContent.setText(messageEntity.getDialogue().getFrom().getContent());
content = messageEntity.getDialogue().getFrom().getContent();
mBinding.messageOriginalTitle.setText(messageEntity.getActivity().getTitle());
targetUrl = messageEntity.getActivity().getImageUrl();
if (TextUtils.isEmpty(targetUrl)) {
@ -500,7 +501,7 @@ public class MessageItemViewHolder extends BaseRecyclerViewHolder<MessageEntity>
case "game_list_comment":
mBinding.messageCommand.setText("评价了你的游戏单");
mBinding.messageContent.setVisibility(View.VISIBLE);
mBinding.messageContent.setText(messageEntity.getComment().getContent());
content = messageEntity.getComment().getContent();
mBinding.messageOriginalTitle.setText(messageEntity.getGameList().getTitle());
targetUrl = messageEntity.getGameList().getCover();
if (TextUtils.isEmpty(targetUrl)) {
@ -527,7 +528,7 @@ public class MessageItemViewHolder extends BaseRecyclerViewHolder<MessageEntity>
case "game_list_comment_reply":
mBinding.messageCommand.setText("回复了你的游戏单评价");
mBinding.messageContent.setVisibility(View.VISIBLE);
mBinding.messageContent.setText(messageEntity.getComment().getContent());
content = messageEntity.getComment().getContent();
mBinding.messageOriginalTitle.setText(messageEntity.getComment().getParent().getContent());
targetUrl = messageEntity.getGameList().getCover();
if (TextUtils.isEmpty(targetUrl)) {
@ -540,6 +541,8 @@ public class MessageItemViewHolder extends BaseRecyclerViewHolder<MessageEntity>
break;
}
TextHelper.highlightTextThatIsWrappedInsideWrapperByDefault(mBinding.messageContent, content);
mBinding.messageOriginalTitle.post(() -> {
ViewGroup.LayoutParams params = mBinding.messageOriginal.getLayoutParams();
if (mBinding.messageOriginalTitle.getLineCount() > 1 || mBinding.messageOriginalIcon.getVisibility() == View.VISIBLE) {

View File

@ -23,7 +23,11 @@ class InstalledGameAdapter(mContext: Context, val games: ArrayList<GameInstall>)
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
val gameInstall = games[position]
holder.itemView.apply {
findViewById<GameIconView>(R.id.game_icon).displayGameIcon(gameInstall.icon, gameInstall.iconSubScript)
findViewById<GameIconView>(R.id.game_icon).displayGameIcon(
gameInstall.icon,
gameInstall.iconSubScript,
gameInstall.iconFloat
)
findViewById<TextView>(R.id.game_name).text = gameInstall.name
}
}

View File

@ -16,7 +16,11 @@ class PersonalItemViewHolder(val binding: CommunityAnswerItemBinding) :
if (entity.community.type == "official_bbs") {
forumIcon?.displayGameIcon(entity.community.icon, null)
} else {
forumIcon?.displayGameIcon(entity.community.game?.getIcon(), entity.community.game?.iconSubscript)
forumIcon?.displayGameIcon(
entity.community.game?.getIcon(),
entity.community.game?.iconSubscript,
entity.community.game?.iconFloat
)
}
forumNameContainer?.setOnClickListener {

View File

@ -80,7 +80,11 @@ class UserCommentHistoryAdapter(
holder.binding.tvComment.setExpandMaxLines(maxDesLines)
holder.binding.tvComment.setIsExpanded(Int.MAX_VALUE == maxDesLines)
holder.binding.gameIcon.displayGameIcon(rating.game.getRawIconIfExisted(), rating.game.iconSubscript)
holder.binding.gameIcon.displayGameIcon(
rating.game.getRawIconIfExisted(),
rating.game.iconSubscript,
rating.game.iconFloat
)
val m = Pattern.compile(RatingEditActivity.LABEL_REGEX).matcher(rating.content)
if (m.find()) {

View File

@ -136,7 +136,11 @@ open class BaseAnswerOrArticleItemViewHolder(itemView: View) : BaseRecyclerViewH
if (entity.bbs.type == "official_bbs") {
forumIcon?.displayGameIcon(entity.bbs.icon, null)
} else {
forumIcon?.displayGameIcon(entity.bbs.game?.getIcon(), entity.bbs.game?.iconSubscript)
forumIcon?.displayGameIcon(
entity.bbs.game?.getIcon(),
entity.bbs.game?.iconSubscript,
entity.bbs.game?.iconFloat
)
}
val contentType = when (entity.type) {

View File

@ -22,7 +22,6 @@ import com.ethanhua.skeleton.SkeletonScreen
import com.facebook.drawee.view.SimpleDraweeView
import com.gh.common.history.HistoryHelper
import com.gh.common.util.*
import com.gh.common.util.DialogUtils
import com.gh.common.util.LogUtils
import com.gh.common.view.RichEditor
import com.gh.gamecenter.ImageViewerActivity
@ -1302,6 +1301,7 @@ open class AnswerDetailFragment : ToolbarFragment() {
interface CommentListener {
fun onCountChange(count: Int)
fun onCommentDraftChange(draft: String)
fun onCommentSuccess(commentId: String)
}
companion object {

View File

@ -183,7 +183,7 @@ class ArticleDetailContentViewHolder(
val icon = if (!entity.icon.isNullOrEmpty()) entity.icon else entity.game?.getIcon()
val iconSubscript =
if (!entity.iconSubscript.isNullOrEmpty()) entity.iconSubscript else entity.game?.iconSubscript
forumIconView.displayGameIcon(icon, iconSubscript)
forumIconView.displayGameIcon(icon, iconSubscript, entity.game?.iconFloat)
forumContainer.setOnClickListener {
DirectUtils.directForumDetail(forumContainer.context, entity.id, "帖子详情")
LogUtils.uploadAccessToBbs(entity.id, "文章内所属论坛")

View File

@ -133,6 +133,7 @@ class ArticleDetailFragment : BaseCommentFragment<CommentItemData, ArticleDetail
}
} else if (requestCode == CommentActivity.REQUEST_CODE && resultCode == Activity.RESULT_OK) {
val commentCount = data?.getIntExtra(CommentActivity.COMMENT_COUNT, 0)
val commentId = data?.getStringExtra(EntranceConsts.KEY_COMMENT_ID)
if (commentCount != 0 && commentCount != null) {
mViewModel.detailEntity?.count?.comment = commentCount
mViewModel.commentCount = commentCount
@ -144,6 +145,10 @@ class ArticleDetailFragment : BaseCommentFragment<CommentItemData, ArticleDetail
if (EntranceConsts.ENTRANCE_WELCOME == mEntrance) {
LogUtils.uploadCommentFromWelcomeDialog()
}
}
if (!commentId.isNullOrEmpty()) {
mViewModel.getSingleCommentDetail(commentId)
} else {
mViewModel.load(LoadType.REFRESH)
}
} else if (requestCode == MoreFunctionPanelDialog.REQUEST_CODE && resultCode == Activity.RESULT_OK) {
@ -374,12 +379,18 @@ class ArticleDetailFragment : BaseCommentFragment<CommentItemData, ArticleDetail
&& mViewModel.detailEntity?.videos.isNullOrEmpty()
&& mScrollToCommentArea
) {
mBinding.inputContainer.bottomCommentIv.performClick()
mBinding.inputContainer.bottomCommentIv.postDelayed({
mBinding.inputContainer.bottomCommentIv.performClick()
}, 200)
mScrollToCommentArea = false
}
}
mViewModel.articlePageFinishedLiveData.observeNonNull(this) {
if (mScrollToCommentArea) {
mBinding.inputContainer.bottomCommentIv.performClick()
mBinding.inputContainer.bottomCommentIv.postDelayed({
mBinding.inputContainer.bottomCommentIv.performClick()
}, 200)
mScrollToCommentArea = false
}
}

View File

@ -4,24 +4,31 @@ import android.app.Application
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.gh.common.util.CollectionUtils
import com.gh.common.util.ErrorHelper
import com.gh.common.util.NewLogUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.common.json.json
import com.gh.gamecenter.common.retrofit.Response
import com.gh.gamecenter.common.syncpage.SyncDataEntity
import com.gh.gamecenter.common.syncpage.SyncFieldConstants
import com.gh.gamecenter.common.syncpage.SyncPageRepository
import com.gh.common.util.*
import com.gh.gamecenter.R
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.common.utils.observableToMain
import com.gh.gamecenter.common.utils.toJson
import com.gh.gamecenter.common.utils.toRequestBody
import com.gh.gamecenter.entity.*
import com.gh.gamecenter.core.utils.GsonUtils
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.energy.EnergyBridge
import com.gh.gamecenter.entity.ActivityLabelEntity
import com.gh.gamecenter.entity.CommentEntity
import com.gh.gamecenter.entity.VoteEntity
import com.gh.gamecenter.eventbus.EBCollectionChanged
import com.gh.gamecenter.eventbus.EBUserFollow
import com.gh.gamecenter.feature.entity.Permissions
import com.gh.gamecenter.qa.comment.base.BaseCommentViewModel
import com.gh.gamecenter.qa.entity.ArticleDetailEntity
import com.gh.gamecenter.common.retrofit.Response
import com.gh.gamecenter.energy.EnergyBridge
import com.gh.gamecenter.feature.entity.Permissions
import com.gh.gamecenter.retrofit.RetrofitManager
import com.google.gson.reflect.TypeToken
import com.lightgame.utils.Utils
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
@ -42,6 +49,7 @@ class ArticleDetailViewModel(
communityId = communityId,
videoId = "",
questionId = "",
gameCollectionId = "",
topCommentId = topCommentId
) {
@ -72,7 +80,11 @@ class ArticleDetailViewModel(
currentSortType.value,
page,
map
)
).map {
mTotal = it.headers().get("total")?.toInt() ?: 0
val type = object : TypeToken<List<CommentEntity>>() {}.type
GsonUtils.gson.fromJson(it.body()?.toJson() ?: "", type)
}
}
override fun mergeResultLiveData() {

View File

@ -6,9 +6,9 @@ import android.content.Intent
import android.content.pm.ActivityInfo
import android.os.Build
import android.os.Bundle
import com.gh.gamecenter.common.base.activity.ToolBarActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.activity.BaseActivity
import com.gh.gamecenter.common.base.activity.ToolBarActivity
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.constant.EntranceConsts.KEY_COMMENT_ID
import com.gh.gamecenter.core.utils.DisplayUtils
@ -63,6 +63,11 @@ class CommentActivity : BaseActivity() {
resultIntent.putExtra(COMMENT_DRAFT, draft)
setResult(Activity.RESULT_OK, resultIntent)
}
override fun onCommentSuccess(commentId: String) {
resultIntent.putExtra(KEY_COMMENT_ID, commentId)
setResult(Activity.RESULT_OK, resultIntent)
}
}
var commentFragment = supportFragmentManager.findFragmentByTag(NewCommentFragment::class.java.name)
if (commentFragment != null) {

View File

@ -16,27 +16,25 @@ import androidx.core.os.bundleOf
import androidx.fragment.app.Fragment
import androidx.lifecycle.Observer
import androidx.recyclerview.widget.RecyclerView
import com.gh.gamecenter.common.base.fragment.BaseDialogWrapperFragment
import com.gh.gamecenter.common.syncpage.SyncDataEntity
import com.gh.gamecenter.common.syncpage.SyncFieldConstants
import com.gh.gamecenter.common.syncpage.SyncPageRepository
import com.gh.common.util.*
import com.gh.common.util.DialogUtils
import com.gh.gamecenter.common.constant.EntranceConsts.KEY_COMMENT_ID
import com.gh.gamecenter.common.view.VerticalItemDecoration
import com.gh.gamecenter.CommentDetailActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.adapter.OnCommentCallBackListener
import com.gh.gamecenter.common.base.fragment.BaseDialogWrapperFragment
import com.gh.gamecenter.common.baselist.ListAdapter
import com.gh.gamecenter.common.baselist.ListFragment
import com.gh.gamecenter.common.callback.ConfirmListener
import com.gh.gamecenter.common.constant.EntranceConsts.KEY_COMMENT_ID
import com.gh.gamecenter.common.eventbus.EBReuse
import com.gh.gamecenter.common.syncpage.SyncDataEntity
import com.gh.gamecenter.common.syncpage.SyncFieldConstants
import com.gh.gamecenter.common.syncpage.SyncPageRepository
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.view.VerticalItemDecoration
import com.gh.gamecenter.core.utils.*
import com.gh.gamecenter.databinding.ItemCommentEditImageBinding
import com.gh.gamecenter.entity.CommentEntity
import com.gh.gamecenter.eventbus.EBCommentSuccess
import com.gh.gamecenter.eventbus.EBDeleteComment
import com.gh.gamecenter.common.eventbus.EBReuse
import com.gh.gamecenter.qa.answer.detail.AnswerDetailFragment
import com.gh.gamecenter.qa.comment.CommentActivity.Companion.GAME_COLLECTION_ID
import com.gh.gamecenter.qa.comment.CommentActivity.Companion.QUESTION_ID
@ -50,7 +48,6 @@ import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
import java.io.File
import java.util.ArrayList
import kotlin.math.abs
open class NewCommentFragment : ListFragment<CommentEntity, NewCommentViewModel>(), OnCommentCallBackListener,
@ -154,6 +151,10 @@ open class NewCommentFragment : ListFragment<CommentEntity, NewCommentViewModel>
updateCommentCount()
if (mCommentListener != null) {
if (apiResponse.data.has("_id")) {
val commentId = apiResponse.data.getString("_id")
mCommentListener?.onCommentSuccess(commentId)
}
mCommentListener?.onCountChange(mCommentCount)
mCommentListener?.onCommentDraftChange("")
}
@ -218,7 +219,8 @@ open class NewCommentFragment : ListFragment<CommentEntity, NewCommentViewModel>
else -> ""
}
ErrorHelper.handleError(requireContext(), errorString, false,
ErrorHelper.handleError(
requireContext(), errorString, false,
{ commentSendBtn.performClick() }, entrance
)
}

View File

@ -6,7 +6,6 @@ import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.gh.gamecenter.common.utils.UploadImageUtils
import com.gh.gamecenter.common.baselist.ListViewModel
import com.gh.gamecenter.common.retrofit.ApiResponse
import com.gh.gamecenter.common.retrofit.BiResponse
@ -14,15 +13,15 @@ import com.gh.gamecenter.common.retrofit.Response
import com.gh.gamecenter.common.syncpage.SyncDataEntity
import com.gh.gamecenter.common.syncpage.SyncFieldConstants
import com.gh.gamecenter.common.syncpage.SyncPageRepository
import com.gh.gamecenter.common.utils.createRequestBodyAny
import com.gh.gamecenter.common.utils.tryCatchInRelease
import com.gh.gamecenter.common.utils.tryWithDefaultCatch
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.utils.GsonUtils
import com.gh.gamecenter.energy.EnergyBridge
import com.gh.gamecenter.entity.CommentDraft
import com.gh.gamecenter.entity.CommentEntity
import com.gh.gamecenter.retrofit.RetrofitManager
import com.gh.gamecenter.room.AppDatabase
import com.gh.gamecenter.room.dao.CommentDraftDao
import com.google.gson.reflect.TypeToken
import com.lightgame.utils.Utils
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
@ -71,10 +70,16 @@ open class NewCommentViewModel(
"time.create:1",
page,
mapOf()
)
).map {
val type = object : TypeToken<List<CommentEntity>>() {}.type
GsonUtils.gson.fromJson(it.body()?.toJson() ?: "", type)
}
CommentType.COMMUNITY_ARTICLE_CONVERSATION -> api.getCommunityArticleCommentConversation(commentId, page)
CommentType.VIDEO -> api.getVideoCommentList(videoId, page, mapOf())
CommentType.VIDEO -> api.getVideoCommentList(videoId, page, mapOf()).map {
val type = object : TypeToken<List<CommentEntity>>() {}.type
GsonUtils.gson.fromJson(it.body()?.toJson() ?: "", type)
}
CommentType.VIDEO_CONVERSATION -> api.getVideoCommentConversationList(videoId, commentId, page)
else -> null
}
@ -85,7 +90,10 @@ open class NewCommentViewModel(
UploadImageUtils.compressAndUploadImageList(
UploadImageUtils.UploadType.comment, pictureList, false,
object : UploadImageUtils.OnUploadImageListListener {
override fun onSuccess(imageUrlMap: LinkedHashMap<String, String>, errorMap: Map<String, Exception>) {
override fun onSuccess(
imageUrlMap: LinkedHashMap<String, String>,
errorMap: Map<String, Exception>
) {
if (errorMap.isNotEmpty()) {
uploadPictureFail(errorMap)
} else {
@ -186,7 +194,8 @@ open class NewCommentViewModel(
deleteCommentDraft(commentEntity)
val apiResponse = ApiResponse<JSONObject>()
apiResponse.data = JSONObject()
val data = response?.string()?.toString()
apiResponse.data = if (data.isNullOrEmpty()) JSONObject() else JSONObject(data)
mPostCommentLiveData.postValue(apiResponse)
commentEntity?.id?.let {
@ -207,20 +216,20 @@ open class NewCommentViewModel(
)
}
if (commentType == CommentType.COMMUNITY_ARTICLE && commentEntity == null) {
if (commentType == CommentType.COMMUNITY_ARTICLE && commentEntity == null && !data.isNullOrEmpty()) {
tryWithDefaultCatch {
EnergyBridge.postEnergyTask(
"comment_community_article",
JSONObject(response?.string()).optString("_id")
JSONObject(data).optString("_id")
)
}
}
if (commentType == CommentType.VIDEO && commentEntity == null) {
if (commentType == CommentType.VIDEO && commentEntity == null && !data.isNullOrEmpty()) {
tryWithDefaultCatch {
EnergyBridge.postEnergyTask(
"comment_video",
JSONObject(response?.string()).optString("_id")
JSONObject(data).optString("_id")
)
}
}

View File

@ -8,11 +8,9 @@ import android.view.View
import android.view.ViewGroup
import androidx.annotation.StringRes
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.util.*
import com.gh.common.util.DialogUtils
import com.gh.common.util.NewLogUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.common.baselist.ListAdapter
@ -79,6 +77,9 @@ abstract class BaseCommentAdapter(
&& oldItem?.commentTop?.accept == newItem?.commentTop?.accept
&& oldItem?.commentTop?.choiceness == newItem?.commentTop?.choiceness
&& oldItem?.commentTop?.me?.isVoted == newItem?.commentTop?.me?.isVoted
&& oldItem?.commentTop?.content == newItem?.commentTop?.content
&& oldItem?.commentTop?.time == newItem?.commentTop?.time
&& oldItem?.commentTop?.images == newItem?.commentTop?.images
&& oldItem?.commentNormal?.vote == newItem?.commentNormal?.vote
&& oldItem?.commentNormal?.reply == newItem?.commentNormal?.reply
&& oldItem?.commentNormal?.me?.isCommentVoted == newItem?.commentNormal?.me?.isCommentVoted
@ -86,6 +87,9 @@ abstract class BaseCommentAdapter(
&& oldItem?.commentNormal?.isTop == newItem?.commentNormal?.isTop
&& oldItem?.commentNormal?.accept == newItem?.commentNormal?.accept
&& oldItem?.commentNormal?.choiceness == newItem?.commentNormal?.choiceness
&& oldItem?.commentNormal?.content == newItem?.commentNormal?.content
&& oldItem?.commentNormal?.time == newItem?.commentNormal?.time
&& oldItem?.commentNormal?.images == newItem?.commentNormal?.images
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {

View File

@ -11,11 +11,13 @@ import com.gh.gamecenter.common.baselist.LoadParams
import com.gh.gamecenter.common.baselist.LoadStatus
import com.gh.gamecenter.common.baselist.LoadType
import com.gh.gamecenter.common.json.json
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.common.retrofit.Response
import com.gh.gamecenter.common.syncpage.SyncDataEntity
import com.gh.gamecenter.common.syncpage.SyncFieldConstants
import com.gh.gamecenter.common.syncpage.SyncPageRepository
import com.gh.gamecenter.common.utils.observableToMain
import com.gh.gamecenter.common.utils.singleToMain
import com.gh.gamecenter.common.utils.toRequestBody
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.entity.CommentDraft
@ -39,9 +41,11 @@ abstract class BaseCommentViewModel(
var videoId: String,
var questionId: String,
var communityId: String,
var gameCollectionId: String,
var topCommentId: String = ""
) : ListViewModel<CommentEntity, CommentItemData>(application) {
protected val mApi: ApiService = RetrofitManager.getInstance().api
protected var mTotal: Int = 0
var currentSortType: SortType = SortType.OLDEST
val loadResultLiveData = MutableLiveData<LoadResult>()
@ -130,6 +134,64 @@ abstract class BaseCommentViewModel(
}
}
@SuppressLint("CheckResult")
fun getSingleCommentDetail(commentId: String) {
val itemDataList = mResultLiveData?.value ?: return
val count = itemDataList.count { it.commentNormal != null }
if (count == 0) {
load(LoadType.REFRESH)
return
}
val single = when {
articleId.isNotEmpty() -> {
mApi.getCommunityArticleComment(commentId)
}
videoId.isNotEmpty() -> {
mApi.getCommunityVideoComment(commentId)
}
questionId.isNotEmpty() -> {
mApi.getCommunityQuestionComment(questionId, commentId)
}
gameCollectionId.isNotEmpty() -> {
mApi.getGameCollectionComment(gameCollectionId, commentId)
}
else -> null
} ?: return
single.compose(singleToMain())
.subscribe(object : BiResponse<CommentEntity>() {
override fun onSuccess(data: CommentEntity) {
when (currentSortType) {
SortType.LATEST -> {
//插入到第一个
val index = itemDataList.indexOfFirst { it.commentNormal != null }
if (index >= 0) {
mTotal++
itemDataList.add(index, CommentItemData(commentNormal = data))
mResultLiveData.postValue(itemDataList)
} else {
load(LoadType.REFRESH)
}
}
SortType.OLDEST -> {
//根据total判断是否插入到最后
if (count >= mTotal) {
mTotal++
val index = itemDataList.indexOfLast { it.commentNormal != null }
itemDataList.add(index + 1, CommentItemData(commentNormal = data))
mResultLiveData.postValue(itemDataList)
} else {
load(LoadType.REFRESH)
}
}
}
}
override fun onFailure(exception: Exception) {
super.onFailure(exception)
load(LoadType.REFRESH)
}
})
}
fun handleTopComment(index: Int, entity: CommentEntity) {
if (getHandleTopCommentCondition(index)) {
isHandleTopComment = true
@ -268,8 +330,13 @@ abstract class BaseCommentViewModel(
observable.compose(observableToMain())
.subscribe(object : Response<ResponseBody>() {
override fun onResponse(response: ResponseBody?) {
mTotal--
hideCommentSuccess()
callback.invoke()
val indexOfFirst = mResultLiveData.value?.indexOfFirst { it.commentNormal?.id == entity.id } ?: -1
if (indexOfFirst >= 0) {
mResultLiveData.value?.removeAt(indexOfFirst)
}
}
override fun onFailure(e: HttpException?) {

View File

@ -4,10 +4,10 @@ import android.annotation.SuppressLint
import android.app.Application
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.gh.gamecenter.entity.CommentEntity
import com.gh.gamecenter.qa.comment.base.BaseCommentViewModel
import com.gh.gamecenter.qa.article.detail.CommentItemData
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.entity.CommentEntity
import com.gh.gamecenter.qa.article.detail.CommentItemData
import com.gh.gamecenter.qa.comment.base.BaseCommentViewModel
import io.reactivex.Observable
import io.reactivex.Single
import io.reactivex.schedulers.Schedulers
@ -19,7 +19,7 @@ class CommentConversationViewModel(
videoId: String = "",
questionId: String = "",
communityId: String = "",
val gameCollectionId: String = "",
gameCollectionId: String = "",
var commentId: String = "",
topCommentId: String = ""
) : BaseCommentViewModel(application, articleId, videoId, questionId, communityId, topCommentId) {

View File

@ -72,7 +72,7 @@ class ChooseForumContainerAdapter(
)
val icon = forumEntity.icon.ifEmpty { forumEntity.game.getIcon() }
holder.binding.forumIcon.displayGameIcon(icon, forumEntity.game.iconSubscript)
holder.binding.forumIcon.displayGameIcon(icon, forumEntity.game.iconSubscript, forumEntity.game.iconFloat)
holder.binding.followTv.visibility = View.GONE
holder.itemView.setOnClickListener {
val tabType = if (type == ChooseForumContainerFragment.ChooseForumType.SEARCH.value) "论坛tab" else ""

View File

@ -15,22 +15,22 @@ import androidx.core.view.ViewCompat
import androidx.lifecycle.Lifecycle
import androidx.recyclerview.widget.RecyclerView
import com.ethanhua.skeleton.Skeleton
import com.gh.gamecenter.common.constant.Constants
import com.gh.common.util.*
import com.gh.common.util.BbsReportHelper
import com.gh.common.util.LogUtils
import com.gh.common.util.NewLogUtils
import com.gh.common.util.SyncDataBetweenPageHelper
import com.gh.gamecenter.ImageViewerActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.common.baselist.ListAdapter
import com.gh.gamecenter.common.baselist.LoadType
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.entity.AdditionalParamsEntity
import com.gh.gamecenter.common.entity.CommunityEntity
import com.gh.gamecenter.common.entity.NormalShareEntity
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.utils.ImageUtils
import com.gh.gamecenter.databinding.FragmentArticleDetailBinding
import com.gh.gamecenter.entity.*
import com.gh.gamecenter.entity.MenuItemEntity
import com.gh.gamecenter.eventbus.EBDeleteDetail
import com.gh.gamecenter.feature.entity.Permissions
import com.gh.gamecenter.login.user.UserManager
@ -45,8 +45,6 @@ import com.gh.gamecenter.qa.questions.edit.QuestionEditActivity
import com.gh.gamecenter.qa.questions.invite.QuestionsInviteActivity
import com.halo.assistant.HaloApp
import org.greenrobot.eventbus.EventBus
import java.util.*
import kotlin.collections.ArrayList
class NewQuestionDetailFragment :
BaseCommentFragment<CommentItemData, NewQuestionDetailViewModel>() {
@ -119,6 +117,7 @@ class NewQuestionDetailFragment :
}
} else if (requestCode == CommentActivity.REQUEST_CODE) {
val commentCount = data.getIntExtra(CommentActivity.COMMENT_COUNT, 0)
val commentId = data.getStringExtra(EntranceConsts.KEY_COMMENT_ID)
if (commentCount != 0) {
// 因为answer赋值会默认加上reply数量所以要减去reply数量才能得出真实的answer数量
mViewModel.questionDetail?.count?.answer =
@ -133,7 +132,11 @@ class NewQuestionDetailFragment :
if (EntranceConsts.ENTRANCE_WELCOME == mEntrance) {
LogUtils.uploadCommentFromWelcomeDialog()
}
mViewModel.load(LoadType.REFRESH)
if (!commentId.isNullOrEmpty()) {
mViewModel.getSingleCommentDetail(commentId)
} else {
mViewModel.load(LoadType.REFRESH)
}
}
} else if (requestCode == MoreFunctionPanelDialog.REQUEST_CODE && resultCode == Activity.RESULT_OK) {
mViewModel.questionDetail?.run {
@ -304,12 +307,18 @@ class NewQuestionDetailFragment :
&& mViewModel.questionDetail?.videos.isNullOrEmpty()
&& mScrollToCommentArea
) {
mBinding.inputContainer.bottomCommentIv.performClick()
mBinding.inputContainer.bottomCommentIv.postDelayed({
mBinding.inputContainer.bottomCommentIv.performClick()
}, 200)
mScrollToCommentArea = false
}
}
mViewModel.questionPageFinishedLiveData.observeNonNull(this) {
if (mScrollToCommentArea) {
mBinding.inputContainer.bottomCommentIv.performClick()
mBinding.inputContainer.bottomCommentIv.postDelayed({
mBinding.inputContainer.bottomCommentIv.performClick()
}, 200)
mScrollToCommentArea = false
}
}

View File

@ -5,27 +5,27 @@ import android.app.Application
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.gh.gamecenter.common.json.json
import com.gh.gamecenter.common.syncpage.SyncDataEntity
import com.gh.gamecenter.common.syncpage.SyncFieldConstants
import com.gh.gamecenter.common.syncpage.SyncPageRepository
import com.gh.common.util.*
import com.gh.common.util.NewLogUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.common.baselist.LoadStatus
import com.gh.gamecenter.common.baselist.LoadType
import com.gh.gamecenter.common.json.json
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.common.retrofit.Response
import com.gh.gamecenter.common.syncpage.SyncDataEntity
import com.gh.gamecenter.common.syncpage.SyncFieldConstants
import com.gh.gamecenter.common.syncpage.SyncPageRepository
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.utils.GsonUtils
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.common.utils.observableToMain
import com.gh.gamecenter.common.utils.singleToMain
import com.gh.gamecenter.common.utils.toRequestBody
import com.gh.gamecenter.entity.CommentEntity
import com.gh.gamecenter.eventbus.EBUserFollow
import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.qa.article.detail.CommentItemData
import com.gh.gamecenter.qa.comment.base.BaseCommentViewModel
import com.gh.gamecenter.qa.entity.QuestionsDetailEntity
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.common.retrofit.Response
import com.gh.gamecenter.common.utils.safelyGetInRelease
import com.google.gson.reflect.TypeToken
import com.lightgame.utils.Utils
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
@ -49,6 +49,7 @@ class NewQuestionDetailViewModel(
communityId = communityId,
videoId = "",
questionId = questionId,
gameCollectionId = "",
topCommentId = topCommentId
) {
var questionRenderedLiveData = MutableLiveData<Boolean>()
@ -93,6 +94,11 @@ class NewQuestionDetailViewModel(
!isHandleTopComment && topCommentId.isNotEmpty() -> map["top_comment_id"] = topCommentId
}
return mApi.getQuestionComment(questionId, currentSortType.value, page, map)
.map {
mTotal = it.headers().get("total")?.toInt() ?: 0
val type = object : TypeToken<List<CommentEntity>>() {}.type
GsonUtils.gson.fromJson(it.body()?.toJson() ?: "", type)
}
}
override fun mergeResultLiveData() {

View File

@ -160,7 +160,7 @@ class QuestionDetailContentViewHolder(
val icon = if (!entity.icon.isNullOrEmpty()) entity.icon else entity.game?.getIcon()
val iconSubscript =
if (!entity.iconSubscript.isNullOrEmpty()) entity.iconSubscript else entity.game?.iconSubscript
forumIconView.displayGameIcon(icon, iconSubscript)
forumIconView.displayGameIcon(icon, iconSubscript, entity.game?.iconFloat)
forumContainer.setOnClickListener {
DirectUtils.directForumDetail(forumContainer.context, entity.id, "问题详情")
LogUtils.uploadAccessToBbs(entity.id, "文章内所属论坛")

View File

@ -6,22 +6,22 @@ import android.os.Bundle
import android.view.View
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.RecyclerView
import com.gh.gamecenter.common.syncpage.SyncDataEntity
import com.gh.gamecenter.common.syncpage.SyncFieldConstants
import com.gh.gamecenter.common.syncpage.SyncPageRepository
import com.gh.common.util.NewLogUtils
import com.gh.gamecenter.common.view.CustomDividerItemDecoration
import com.gh.gamecenter.R
import com.gh.gamecenter.common.baselist.LazyListFragment
import com.gh.gamecenter.common.baselist.ListAdapter
import com.gh.gamecenter.common.baselist.LoadType
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.mvvm.Status
import com.gh.gamecenter.common.syncpage.SyncDataEntity
import com.gh.gamecenter.common.syncpage.SyncFieldConstants
import com.gh.gamecenter.common.syncpage.SyncPageRepository
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.view.CustomDividerItemDecoration
import com.gh.gamecenter.common.view.SegmentedFilterView
import com.gh.gamecenter.databinding.FragmentVideoCommentListBinding
import com.gh.gamecenter.feature.entity.ForumVideoEntity
import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.common.mvvm.Status
import com.gh.gamecenter.qa.article.detail.CommentItemData
import com.gh.gamecenter.qa.comment.CommentActivity
import com.gh.gamecenter.qa.comment.base.BaseCommentViewModel
@ -156,12 +156,12 @@ class VideoCommentFragment : LazyListFragment<CommentItemData, VideoCommentViewM
if (data == null || resultCode != Activity.RESULT_OK) return
if (requestCode == CommentActivity.REQUEST_CODE) {
val commentCount = data.getIntExtra(CommentActivity.COMMENT_COUNT, 0)
val commentId = data.getStringExtra(EntranceConsts.KEY_COMMENT_ID)
if (commentCount != 0) {
mListViewModel.videoDetail?.let {
it.count.comment = commentCount
mBinding.allCommentCountTv.text = it.count.comment.toString()
mVideoDetailViewModel.updateDetailLiveData.postValue(it)
mListViewModel.load(LoadType.REFRESH)
SyncPageRepository.postSyncData(
SyncDataEntity(
mVideoId,
@ -172,6 +172,11 @@ class VideoCommentFragment : LazyListFragment<CommentItemData, VideoCommentViewM
)
}
}
if (!commentId.isNullOrEmpty()) {
mListViewModel.getSingleCommentDetail(commentId)
} else {
mListViewModel.load(LoadType.REFRESH)
}
}
}

View File

@ -5,10 +5,13 @@ import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.gh.gamecenter.common.baselist.LoadStatus
import com.gh.gamecenter.common.utils.toJson
import com.gh.gamecenter.core.utils.GsonUtils
import com.gh.gamecenter.entity.CommentEntity
import com.gh.gamecenter.feature.entity.ForumVideoEntity
import com.gh.gamecenter.qa.comment.base.BaseCommentViewModel
import com.gh.gamecenter.qa.article.detail.CommentItemData
import com.gh.gamecenter.qa.comment.base.BaseCommentViewModel
import com.google.gson.reflect.TypeToken
import com.halo.assistant.HaloApp
import io.reactivex.Observable
@ -17,7 +20,7 @@ class VideoCommentViewModel(
videoId: String,
bbsId: String,
topCommentId: String
) : BaseCommentViewModel(application, "", videoId, "", bbsId, topCommentId) {
) : BaseCommentViewModel(application, "", videoId, "", bbsId, "", topCommentId) {
var videoDetail: ForumVideoEntity? = null
val deleteCommentLiveData = MutableLiveData<Boolean>()
@ -29,6 +32,11 @@ class VideoCommentViewModel(
map["top_comment_id"] = topCommentId
}
return mApi.getVideoCommentList(videoId, page, map)
.map {
mTotal = it.headers().get("total")?.toInt() ?: 0
val type = object : TypeToken<List<CommentEntity>>() {}.type
GsonUtils.gson.fromJson(it.body()?.toJson() ?: "", type)
}
}
override fun mergeResultLiveData() {

View File

@ -38,6 +38,7 @@ import com.gh.gamecenter.entity.GameColumnCollection;
import com.gh.gamecenter.entity.GameDigestEntity;
import com.gh.gamecenter.entity.GameGuidePopupEntity;
import com.gh.gamecenter.entity.GameNavigationWrapper;
import com.gh.gamecenter.entity.GameServerTestV2Entity;
import com.gh.gamecenter.entity.GameVideoInfo;
import com.gh.gamecenter.entity.GamesCollectionDetailEntity;
import com.gh.gamecenter.entity.GamesCollectionEntity;
@ -73,6 +74,7 @@ import com.gh.gamecenter.entity.ServersGameCategory;
import com.gh.gamecenter.entity.SidebarsEntity;
import com.gh.gamecenter.entity.SignEntity;
import com.gh.gamecenter.entity.SpecialCatalogEntity;
import com.gh.gamecenter.entity.StartPointEntity;
import com.gh.gamecenter.entity.SubjectEntity;
import com.gh.gamecenter.entity.SubjectRecommendEntity;
import com.gh.gamecenter.entity.SubjectRefreshEntity;
@ -1140,7 +1142,7 @@ public interface ApiService {
* 获取社区文章评论列表.可以分页
*/
@GET("communities/articles/{article_id}/comments")
Observable<List<CommentEntity>> getCommunityArticleCommentList(@Path("article_id") String articleId,
Observable<retrofit2.Response<JsonArray>> getCommunityArticleCommentList(@Path("article_id") String articleId,
@Query("sort") String type,
@Query("page") int page,
@QueryMap Map<String, Object> params);
@ -1604,7 +1606,7 @@ public interface ApiService {
* 获取评论列表.可以分页
*/
@GET("videos/{video_id}/comments")
Observable<List<CommentEntity>> getVideoCommentList(@Path("video_id") String videoId, @Query("page") int page, @QueryMap Map<String, Object> params);
Observable<retrofit2.Response<JsonArray>> getVideoCommentList(@Path("video_id") String videoId, @Query("page") int page, @QueryMap Map<String, Object> params);
/**
* 获取评论的对话列表.
@ -2420,7 +2422,7 @@ public interface ApiService {
* 问题评论(回答)列表
*/
@GET("bbses/questions/{question_id}/comments")
Observable<List<CommentEntity>> getQuestionComment(@Path("question_id") String questionId, @Query("sort") String type, @Query("page") int page, @QueryMap Map<String, Object> params);
Observable<retrofit2.Response<JsonArray>> getQuestionComment(@Path("question_id") String questionId, @Query("sort") String type, @Query("page") int page, @QueryMap Map<String, Object> params);
/**
* 对社区问题发布评论(回答)
@ -2723,7 +2725,7 @@ public interface ApiService {
* 游戏单评论列表
*/
@GET("api_go/game_list/{game_list_id}/comment")
Single<List<CommentEntity>> getGameCollectionComments(@Path("game_list_id") String id,
Single<retrofit2.Response<JsonArray>> getGameCollectionComments(@Path("game_list_id") String id,
@Query("page") int page,
@QueryMap Map<String, Object> params);
@ -3025,4 +3027,16 @@ public interface ApiService {
@GET("games/{game_id}/archives/status")
Single<ResponseBody> getArchiveStatus(@Path("game_id") String gameId);
/**
* 新游开测-详情列表页-时间轴起始点
*/
@GET("columns/tests/v2/start_point")
Observable<StartPointEntity> getStartPoint(@Query("filter") String filter);
/**
* 新游开测-详情列表(含分页)
*/
@GET("columns/tests/v2")
Observable<GameServerTestV2Entity> getServerTestV2(@Query("filter") String filter);
}

View File

@ -0,0 +1,18 @@
package com.gh.gamecenter.room.converter
import androidx.room.TypeConverter
import com.gh.gamecenter.common.entity.IconFloat
import com.gh.gamecenter.common.utils.toJson
import com.gh.gamecenter.common.utils.toObject
class IconFloatConverter {
@TypeConverter
fun toIconFloatString(data: IconFloat?): String {
return data?.toJson() ?: ""
}
@TypeConverter
fun toIconFloat(token: String?): IconFloat {
return token?.toObject() ?: IconFloat()
}
}

View File

@ -19,6 +19,7 @@ import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.feature.exposure.ExposureSource
class SearchGameIndexItemViewHolder(var binding: SearchGameIndexItemBinding) : RecyclerView.ViewHolder(binding.root) {
var contentTag: GameEntity.ContentTag? = null
fun initServerType(gameEntity: GameEntity) {
val serverLabel = gameEntity.serverLabel
when {

View File

@ -247,7 +247,8 @@ class SearchGameResultAdapter(
|| gameEntity.contentTag!!.server
|| gameEntity.contentTag!!.isBbsExists)
tagContainer.goneIf(!isShowTag)
if (isShowTag) {
if (isShowTag && gameEntity.contentTag != holder.contentTag) {
holder.contentTag = gameEntity.contentTag
bottomDivider.visibility = View.VISIBLE
val screenWidth = mContext.resources.displayMetrics.widthPixels
val tagWidth = (screenWidth - (16F * 2 + 8F * 3).dip2px()) / 4

View File

@ -0,0 +1,147 @@
package com.gh.gamecenter.servers.gametest2
import android.graphics.drawable.ColorDrawable
import android.view.View
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.util.DownloadItemUtils
import com.gh.gamecenter.GameDetailActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.adapter.viewholder.GameViewHolder
import com.gh.gamecenter.common.base.BaseRecyclerViewHolder
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.view.DrawableView
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.core.utils.RandomUtils
import com.gh.gamecenter.core.utils.TimeUtils
import com.gh.gamecenter.databinding.ItemGameServerTestBigImageBinding
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.feature.game.GameItemViewHolder
import com.shuyu.gsyvideoplayer.builder.GSYVideoOptionBuilder
class GameBigImageViewHolder(val binding: ItemGameServerTestBigImageBinding) :
BaseRecyclerViewHolder<Any>(binding.root) {
fun bindAttachGame(
holder: GameBigImageViewHolder,
gameEntity: GameEntity,
adapter: RecyclerView.Adapter<out RecyclerView.ViewHolder>,
entrance: String,
exposureEvent: ExposureEvent
) {
holder.bindGameInfo(gameEntity, adapter, exposureEvent, entrance)
holder.binding.gameImage.goneIf(gameEntity.topVideo != null || gameEntity.homeSetting.image.isEmpty()) {
ImageUtils.display(binding.gameImage, gameEntity.homeSetting.image)
val hierarchy = binding.gameImage.hierarchy
try {
hierarchy.setPlaceholderImage(ColorDrawable(gameEntity.homeSetting.placeholderColor.hexStringToIntColor()))
} catch (ignore: Throwable) {
hierarchy.setPlaceholderImage(RandomUtils.getRandomPlaceholderColor())
}
}
holder.binding.autoVideoView.goneIf(gameEntity.topVideo == null) {
if (!holder.binding.autoVideoView.isInPlayingState) {
GSYVideoOptionBuilder()
.setIsTouchWiget(false)
.setUrl(gameEntity.topVideo?.url ?: "")
.setRotateViewAuto(false)
.setCacheWithPlay(true)
.setRotateWithSystem(false)
.setReleaseWhenLossAudio(true)
.setLooping(false)
.setShowFullAnimation(false)
.build(holder.binding.autoVideoView)
holder.binding.autoVideoView.updateThumb(gameEntity.topVideo?.poster ?: "")
holder.binding.autoVideoView.setParamsData(gameEntity, gameEntity.homeSetting.placeholderColor)
holder.binding.autoVideoView.setOnVideoClickListener { holder.itemView.performClick() }
}
}
holder.itemView.setOnClickListener {
GameDetailActivity.startGameDetailActivity(
binding.root.context,
gameEntity.id,
"(${entrance}-游戏[" + gameEntity.name + "])",
exposureEvent
)
}
}
private fun bindGameInfo(
gameEntity: GameEntity,
adapter: RecyclerView.Adapter<out RecyclerView.ViewHolder>,
exposureEvent: ExposureEvent?,
entrance: String
) {
binding.gameIcon.displayGameIcon(gameEntity)
binding.gameName.text = gameEntity.name
binding.gameBrief.text = gameEntity.brief
binding.timeTv.text = TimeUtils.getFormatTime(gameEntity.time?.time ?: 0L, "HH:mm")
binding.gameName.setTextColor(R.color.text_title.toColor(binding.root.context))
binding.gameBrief.setTextColor(R.color.text_subtitleDesc.toColor(binding.root.context))
val color: Int
when (gameEntity.eventType) {
"test" -> {
color = "#2906CEA8".hexStringToIntColor()
binding.statusTv.background = DrawableView.getCornerGradientDrawable(color, color, 8F)
binding.statusTv.setTextColor(R.color.theme_green.toColor(binding.statusTv.context))
binding.statusTv.text = "测试"
}
"first" -> {
color = "#292496FF".hexStringToIntColor()
binding.statusTv.background = DrawableView.getCornerGradientDrawable(color, color, 8F)
binding.statusTv.setTextColor(R.color.theme_font.toColor(binding.statusTv.context))
binding.statusTv.text = "首发"
}
"update" -> {
color = "#29FFA142".hexStringToIntColor()
binding.statusTv.background = DrawableView.getCornerGradientDrawable(color, color, 8F)
binding.statusTv.setTextColor(R.color.theme_yellow.toColor(binding.statusTv.context))
binding.statusTv.text = "更新"
}
else -> {
//Do nothing
}
}
GameItemViewHolder.initGameSubtitle(gameEntity, binding.gameSubtitleTv, null, binding.root, false) {
binding.gameSubtitleTv.maxWidth =
DisplayUtils.getScreenWidth() - (if (gameEntity.adIconActive) 131F.dip2px() else 156F.dip2px())
}
DownloadItemUtils.setOnClickListener(
binding.root.context,
binding.downloadBtn,
gameEntity,
position,
adapter,
entrance,
"",
exposureEvent
)
DownloadItemUtils.updateItem(
binding.root.context,
gameEntity,
GameViewHolder(binding.root).apply {
gameDownloadBtn = binding.downloadBtn
multiVersionDownloadTv = binding.multiVersionDownloadTv
gameDownloadTips = binding.downloadTipsLottie
},
true
)
ConstraintSet().apply {
clone(binding.gameSubtitleTv.parent as ConstraintLayout)
clear(binding.gameSubtitleTv.id, ConstraintSet.END)
if (binding.downloadBtn.visibility == View.VISIBLE) {
connect(binding.gameSubtitleTv.id, ConstraintSet.END, binding.downloadBtn.id, ConstraintSet.START)
}else {
connect(binding.gameSubtitleTv.id, ConstraintSet.END, ConstraintSet.PARENT_ID, ConstraintSet.END)
}
setMargin(binding.gameSubtitleTv.id, ConstraintSet.END, 16F.dip2px())
applyTo(binding.gameSubtitleTv.parent as ConstraintLayout)
}
}
}

View File

@ -0,0 +1,40 @@
package com.gh.gamecenter.servers.gametest2
import android.content.Context
import android.content.Intent
import android.os.Bundle
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.activity.ToolBarActivity
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.utils.updateStatusBarColor
class GameServerTestV2Activity : ToolBarActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
updateStatusBarColor(R.color.background_white, R.color.background_white)
setNavigationTitle("新游开测")
}
override fun provideNormalIntent(): Intent {
return getTargetIntent(this, GameServerTestV2Activity::class.java, GameServerTestV2Fragment::class.java)
}
override fun onDarkModeChanged() {
super.onDarkModeChanged()
updateStatusBarColor(R.color.background_white, R.color.background_white)
}
companion object {
fun getIntent(context: Context, entrance: String): Intent {
val bundle = Bundle()
bundle.putString(EntranceConsts.KEY_ENTRANCE, entrance)
return getTargetIntent(
context,
GameServerTestV2Activity::class.java,
GameServerTestV2Fragment::class.java,
bundle
)
}
}
}

View File

@ -0,0 +1,198 @@
package com.gh.gamecenter.servers.gametest2
import android.graphics.Color
import android.graphics.Typeface
import android.os.Bundle
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.widget.LinearLayout
import android.widget.PopupWindow
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.vectordrawable.graphics.drawable.VectorDrawableCompat
import com.gh.common.util.NewFlatLogUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.fragment.LazyFragment
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.utils.dip2px
import com.gh.gamecenter.common.utils.toColor
import com.gh.gamecenter.common.utils.toDrawable
import com.gh.gamecenter.common.utils.viewModelProviderFromParent
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.databinding.FragmentGameServerTestV2Binding
import com.gh.gamecenter.databinding.PopupFilterGameTypeBinding
class GameServerTestV2Fragment : LazyFragment() {
private var mBinding: FragmentGameServerTestV2Binding? = null
private var mViewModel: GameServerTestV2ViewModel? = null
private var mPopupWindow: PopupWindow? = null
private var mCurrentFragment: GameServerTestV2ListFragment? = null
override fun getRealLayoutId(): Int = R.layout.fragment_game_server_test_v2
override fun onRealLayoutInflated(inflatedView: View) {
super.onRealLayoutInflated(inflatedView)
mBinding = FragmentGameServerTestV2Binding.bind(inflatedView)
}
override fun onFragmentFirstVisible() {
mViewModel = viewModelProviderFromParent()
super.onFragmentFirstVisible()
mViewModel?.selectedTimeFilterLiveData?.observe(this) {
mBinding?.filterView?.updateSelectedFilter(it)
}
changeFragment()
}
override fun initRealView() {
super.initRealView()
mBinding?.filterView?.setupFilter(mViewModel?.timeFilterList!!, mViewModel?.selectedTimeFilterLiveData?.value) {
mViewModel?.setSelectedTimeFilter(it)
mCurrentFragment?.changeTimeFilter()
}
mBinding?.categoryContainer?.setOnClickListener {
showSelectionPopupWindow {
mViewModel?.selectedCategoryFilter = it
mBinding?.categoryTv?.text = it
val drawable = VectorDrawableCompat.create(resources, R.drawable.ic_filter_arrow, null)
if (it != mViewModel?.categoryFilterList?.get(0)) {
mBinding?.categoryTv?.setTextColor(R.color.theme_font.toColor(requireContext()))
drawable?.setTint(R.color.theme_font.toColor(requireContext()))
} else {
mBinding?.categoryTv?.setTextColor(R.color.text_subtitleDesc.toColor(requireContext()))
drawable?.setTint(R.color.text_subtitleDesc.toColor(requireContext()))
}
mBinding?.arrowIv?.setImageDrawable(drawable)
mViewModel?.setSelectedTimeFilter(GameServerTestV2ViewModel.TODAY_GAME)
mCurrentFragment?.changeCategoryFilter()
}
}
mBinding?.filterGroup?.setOnCheckedChangeListener { _, checkedId ->
when (checkedId) {
R.id.recommendRb -> {
mViewModel?.tabFilter = GameServerTestV2ViewModel.TestFilter.RECOMMEND
NewFlatLogUtils.logGameTestDetailTabClick("推荐")
changeFragment()
}
R.id.allRb -> {
mViewModel?.tabFilter = GameServerTestV2ViewModel.TestFilter.ALL
NewFlatLogUtils.logGameTestDetailTabClick("全部")
changeFragment()
}
else -> {
//Do nothing
}
}
}
}
private fun showSelectionPopupWindow(selectedCallback: ((String) -> Unit)?) {
val binding = PopupFilterGameTypeBinding.inflate(LayoutInflater.from(requireContext()), null, false)
val popupWindow = PopupWindow(
binding.root,
LinearLayout.LayoutParams.MATCH_PARENT,
LinearLayout.LayoutParams.WRAP_CONTENT
).apply { mPopupWindow = this }
for (filter in mViewModel?.categoryFilterList!!) {
val itemWidth = (DisplayUtils.getScreenWidth() - 104F.dip2px()) / 4
val item = getItemTextView(filter, itemWidth)
binding.flexbox.addView(item)
item.tag = filter
toggleHighlightedTextView(item, mViewModel?.selectedCategoryFilter == filter)
item.setOnClickListener {
toggleHighlightedTextView(item, true)
selectedCallback?.invoke(filter)
popupWindow.dismiss()
}
}
val originalColor = mBinding?.categoryTv?.textColors
var drawable = VectorDrawableCompat.create(resources, R.drawable.ic_filter_arrow, null)
drawable?.setTint(R.color.theme_font.toColor(requireContext()))
mBinding?.arrowIv?.rotation = 0F
mBinding?.arrowIv?.setImageDrawable(drawable)
mBinding?.categoryTv?.setTextColor(R.color.theme_font.toColor(requireContext()))
popupWindow.setOnDismissListener {
drawable = VectorDrawableCompat.create(resources, R.drawable.ic_filter_arrow, null)
drawable?.setTint(originalColor?.defaultColor ?: 0)
mBinding?.arrowIv?.rotation = 180F
mBinding?.arrowIv?.setImageDrawable(drawable)
mBinding?.categoryTv?.setTextColor(originalColor)
}
binding.background.setOnClickListener {
popupWindow.dismiss()
mPopupWindow = null
}
popupWindow.isTouchable = true
popupWindow.isFocusable = true
popupWindow.animationStyle = 0
popupWindow.showAsDropDown(mBinding?.filterContainer, 0, 0)
}
private fun getItemTextView(type: String, width: Int): TextView {
return TextView(requireContext()).apply {
text = type
includeFontPadding = false
textSize = 12F
gravity = Gravity.CENTER
setTypeface(Typeface.DEFAULT, Typeface.BOLD)
setTextColor(R.color.white.toColor(context))
val params = LinearLayout.LayoutParams(width, 24F.dip2px())
layoutParams = params
}
}
private fun toggleHighlightedTextView(targetTextView: TextView, highlightIt: Boolean) {
if (highlightIt) {
targetTextView.background = ContextCompat.getDrawable(targetTextView.context, R.drawable.bg_tag_text)
targetTextView.setTextColor(Color.WHITE)
} else {
targetTextView.background = null
targetTextView.setTextColor(ContextCompat.getColor(targetTextView.context, R.color.text_757575))
}
}
private fun changeFragment() {
mViewModel?.selectedTimeFilterLiveData?.value = mViewModel?.timeFilterList?.get(1) ?: ""
mBinding?.filterView?.updateSelectedFilter(mViewModel?.selectedTimeFilterLiveData?.value ?: "")
mCurrentFragment = if (mViewModel?.tabFilter == GameServerTestV2ViewModel.TestFilter.RECOMMEND) {
childFragmentManager.findFragmentByTag(GameServerTestV2ViewModel.TestFilter.RECOMMEND.value) as? GameServerTestV2ListFragment
?: GameServerTestV2ListFragment()
} else {
childFragmentManager.findFragmentByTag(GameServerTestV2ViewModel.TestFilter.ALL.value) as? GameServerTestV2ListFragment
?: GameServerTestV2ListFragment()
}
val bundle = requireArguments().clone() as Bundle
bundle.putString(EntranceConsts.KEY_FILTER, mViewModel?.tabFilter?.value)
mCurrentFragment?.arguments = bundle
childFragmentManager
.beginTransaction()
.replace(R.id.contentContainer, mCurrentFragment!!, mViewModel?.tabFilter?.value)
.commitAllowingStateLoss()
}
override fun onDarkModeChanged() {
super.onDarkModeChanged()
mBinding?.filterView?.updateFilterRecyclerView()
mBinding?.recommendRb?.setTextColor(
ContextCompat.getColorStateList(
requireContext(),
R.color.game_server_test_rg_button_selector
)
)
mBinding?.recommendRb?.background = R.drawable.game_server_test_rg_button_selector.toDrawable(requireContext())
mBinding?.allRb?.setTextColor(
ContextCompat.getColorStateList(
requireContext(),
R.color.game_server_test_rg_button_selector
)
)
mBinding?.allRb?.background = R.drawable.game_server_test_rg_button_selector.toDrawable(requireContext())
}
}

View File

@ -0,0 +1,197 @@
package com.gh.gamecenter.servers.gametest2
import android.content.Context
import android.util.SparseArray
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.exposure.IExposable
import com.gh.common.util.DownloadItemUtils
import com.gh.gamecenter.GameDetailActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.adapter.viewholder.GameViewHolder
import com.gh.gamecenter.common.baselist.ListAdapter
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.viewholder.FooterViewHolder
import com.gh.gamecenter.core.utils.StringUtils
import com.gh.gamecenter.databinding.ItemGameServerTestTimeBinding
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.game.GameItemViewHolder
class GameServerTestV2ListAdapter(
val context: Context,
private val mEntrance: String,
private var mGameServerTestV2ViewModel: GameServerTestV2ViewModel?,
private var mBasicExposureSource: List<ExposureSource>?,
private var mOuterSequence: Int,
) : ListAdapter<GameServerTestV2ListViewModel.ItemData>(context), IExposable {
private val mExposureEventArray: SparseArray<ExposureEvent> = SparseArray()
override fun areItemsTheSame(
oldItem: GameServerTestV2ListViewModel.ItemData?,
newItem: GameServerTestV2ListViewModel.ItemData?
): Boolean {
if (oldItem?.time != null && newItem?.time != null) {
return oldItem.time == newItem.time
}
if (oldItem?.game != null && newItem?.game != null) {
return oldItem.game?.id == newItem.game?.id
}
return false
}
override fun getItemViewType(position: Int): Int {
if (position == mEntityList.size) {
return VIEW_TYPE_FOOTER
}
return when {
mEntityList[position].time != null -> VIEW_TYPE_TIME
mEntityList[position].isBigImage -> VIEW_TYPE_BIG_IMAGE_ITEM
else -> VIEW_TYPE_ITEM
}
}
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): RecyclerView.ViewHolder {
return when (viewType) {
VIEW_TYPE_FOOTER -> {
FooterViewHolder(mLayoutInflater.inflate(R.layout.refresh_footerview, parent, false))
}
VIEW_TYPE_TIME -> {
GameServerTestTimeViewHolder(parent.toBinding())
}
VIEW_TYPE_BIG_IMAGE_ITEM -> {
GameBigImageViewHolder(parent.toBinding())
}
else -> {
GameItemViewHolder(parent.toBinding())
}
}
}
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
when (holder) {
is GameItemViewHolder -> {
val itemData = mEntityList[position]
val gameEntity = itemData.game!!
val isTheLastOfTheLatestConsecutiveGame = itemData.isTheLastOfTheLatestConsecutiveGame
holder.itemView.setPadding(
16F.dip2px(),
8F.dip2px(),
16F.dip2px(),
if (isTheLastOfTheLatestConsecutiveGame) 16F.dip2px() else 8F.dip2px()
)
holder.bindGameItem(gameEntity, forceShowSubtitle = true)
initGameItemViewHolder(gameEntity, holder, position)
}
is GameBigImageViewHolder -> {
val gameEntity = mEntityList[position].game!!
val exposureEvent = putExposureEvent(gameEntity, position)
holder.bindAttachGame(
holder,
gameEntity,
this,
"新游开测",
exposureEvent
)
}
is GameServerTestTimeViewHolder -> {
holder.binding.timeTv.text = mEntityList[position].time
}
is FooterViewHolder -> {
initFooterViewHolder(holder)
}
}
}
private fun putExposureEvent(
gameEntity: GameEntity,
position: Int
): ExposureEvent {
val exposureSources = ArrayList<ExposureSource>()
val tabFilter =
if (mGameServerTestV2ViewModel?.tabFilter == GameServerTestV2ViewModel.TestFilter.RECOMMEND) {
"推荐"
} else {
"全部"
}
val selectedCategoryFilter = mGameServerTestV2ViewModel?.selectedCategoryFilter
val selectedTimeFilter = mGameServerTestV2ViewModel?.selectedTimeFilterLiveData?.value
exposureSources.add(
ExposureSource(
"新游开测",
"${tabFilter}-${selectedCategoryFilter}-${selectedTimeFilter}-${gameEntity.testTime}"
)
)
val exposureEvent = ExposureEvent.createEventWithSourceConcat(
gameEntity = gameEntity.apply {
outerSequence = mOuterSequence
sequence = position
},
basicSource = mBasicExposureSource ?: listOf(),
source = exposureSources
)
mExposureEventArray.put(position, exposureEvent)
return exposureEvent
}
private fun initGameItemViewHolder(gameEntity: GameEntity, viewHolder: GameItemViewHolder, position: Int) {
val exposureEvent = putExposureEvent(gameEntity, position)
DownloadItemUtils.setOnClickListener(
mContext,
viewHolder.binding.downloadBtn, gameEntity, position, this,
StringUtils.buildString(mEntrance, "+(新游开测[", position.toString(), "])"),
StringUtils.buildString("新游开测:", gameEntity.name),
exposureEvent
)
DownloadItemUtils.updateItem(
mContext,
gameEntity,
GameViewHolder(viewHolder.binding),
true,
"star&brief"
)
viewHolder.binding.gameDes.text = gameEntity.brief
viewHolder.itemView.setOnClickListener {
GameDetailActivity.startGameDetailActivity(
mContext, gameEntity,
StringUtils.buildString(mEntrance, "+(新游开测[", viewHolder.adapterPosition.toString(), "])"),
traceEvent = exposureEvent
)
}
}
private fun initFooterViewHolder(viewHolder: FooterViewHolder) {
viewHolder.run {
itemView.setBackgroundColor(R.color.background.toColor(mContext))
loading.visibility = View.GONE
itemView.isClickable = false
hint.setText(R.string.load_over_hint)
}
}
override fun getItemCount(): Int = if (mEntityList.isEmpty()) 0 else mEntityList.size + 1
companion object {
const val VIEW_TYPE_TIME = 0
const val VIEW_TYPE_ITEM = 1
const val VIEW_TYPE_BIG_IMAGE_ITEM = 2
const val VIEW_TYPE_FOOTER = 3
}
class GameServerTestTimeViewHolder(var binding: ItemGameServerTestTimeBinding) :
RecyclerView.ViewHolder(binding.root)
override fun getEventByPosition(pos: Int): ExposureEvent? {
return mExposureEventArray.get(pos)
}
override fun getEventListByPosition(pos: Int): List<ExposureEvent>? {
return null
}
}

View File

@ -0,0 +1,359 @@
package com.gh.gamecenter.servers.gametest2
import android.os.Bundle
import android.view.View
import android.widget.FrameLayout
import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.ethanhua.skeleton.Skeleton
import com.gh.common.exposure.ExposureListener
import com.gh.common.util.DialogUtils
import com.gh.common.util.DownloadItemUtils
import com.gh.common.util.NewFlatLogUtils
import com.gh.common.xapk.XapkInstaller
import com.gh.common.xapk.XapkUnzipStatus
import com.gh.download.DownloadManager
import com.gh.gamecenter.R
import com.gh.gamecenter.common.baselist.LazyListFragment
import com.gh.gamecenter.common.baselist.ListAdapter
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.utils.goneIf
import com.gh.gamecenter.common.utils.safelyGetInRelease
import com.gh.gamecenter.common.utils.viewModelProvider
import com.gh.gamecenter.common.utils.viewModelProviderFromParent
import com.gh.gamecenter.core.utils.MD5Utils
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.databinding.FragmentGameServerTestV2ListBinding
import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.gh.gamecenter.feature.exposure.ExposureSource
import com.gh.gamecenter.home.video.ScrollCalculatorHelper
import com.halo.assistant.HaloApp
import com.lightgame.download.DataWatcher
import com.lightgame.download.DownloadEntity
import org.greenrobot.eventbus.Subscribe
import org.greenrobot.eventbus.ThreadMode
class GameServerTestV2ListFragment :
LazyListFragment<GameServerTestV2ListViewModel.ItemData, GameServerTestV2ListViewModel>() {
private var mBinding: FragmentGameServerTestV2ListBinding? = null
private lateinit var mExposureListener: ExposureListener
private lateinit var mScrollCalculatorHelper: ScrollCalculatorHelper
private var mAdapter: GameServerTestV2ListAdapter? = null
private var mGameServerTestV2ViewModel: GameServerTestV2ViewModel? = null
private var mTabFilterValue: String = ""
private var mSupremeSelectedTimeFilter: String? = null // 手动选择的日期,优先级高,当它存在时忽略滚动的选中
private val dataWatcher: DataWatcher = object : DataWatcher() {
override fun onDataChanged(downloadEntity: DownloadEntity) {
val locationList = mListViewModel?.locationMap?.get(downloadEntity.packageName)
if (locationList != null) {
for (location in locationList) {
mListViewModel.obsListData?.value?.safelyGetInRelease(location)?.game?.let { gameEntity ->
DownloadItemUtils.processDate(gameEntity, downloadEntity, mAdapter, location)
}
}
if (XapkUnzipStatus.FAILURE.name == downloadEntity.meta[XapkInstaller.XAPK_UNZIP_STATUS]) {
for (position in locationList) {
val targetView = mListRv.layoutManager?.findViewByPosition(position)
if (targetView != null) {
DialogUtils.showUnzipFailureDialog(requireContext(), downloadEntity)
break
}
}
}
}
}
}
override fun getRealLayoutId(): Int = R.layout.fragment_game_server_test_v2_list
override fun provideListViewModel(): GameServerTestV2ListViewModel {
return viewModelProvider(
GameServerTestV2ListViewModel.Factory(
HaloApp.getInstance(),
mGameServerTestV2ViewModel
)
)
}
override fun onCreate(savedInstanceState: Bundle?) {
mGameServerTestV2ViewModel = viewModelProviderFromParent()
val filter = requireArguments().getString(EntranceConsts.KEY_FILTER, "")
mTabFilterValue = if (filter == GameServerTestV2ViewModel.TestFilter.RECOMMEND.value) {
"推荐"
} else {
"全部"
}
super.onCreate(savedInstanceState)
}
override fun onRealLayoutInflated(inflatedView: View) {
super.onRealLayoutInflated(inflatedView)
mBinding = FragmentGameServerTestV2ListBinding.bind(inflatedView)
}
override fun initRealView() {
super.initRealView()
mListRefresh?.isEnabled = false
mScrollCalculatorHelper = ScrollCalculatorHelper(mListRv, R.id.autoVideoView, 0)
}
override fun initSkeletonScreen() {
mSkeletonScreen = Skeleton.bind(mBinding?.skeleton)
.shimmer(true)
.angle(Constants.SHIMMER_ANGLE)
.color(R.color.skeleton_shimmer_color)
.duration(Constants.SHIMMER_DURATION)
.maskWidth(Constants.MASK_WIDTH)
.gradientCenterColorWidth(Constants.GRADIENT_CENTER_COLOR_WIDTH)
.load(R.layout.fragment_game_server_test_v2_skeleton)
.show()
}
override fun onFragmentFirstVisible() {
super.onFragmentFirstVisible()
mListRv.clearOnScrollListeners()
mExposureListener = ExposureListener(this, mAdapter!!)
mListRv.addOnScrollListener(mExposureListener)
mListRv.addOnScrollListener(object : RecyclerView.OnScrollListener() {
override fun onScrolled(recyclerView: RecyclerView, dx: Int, dy: Int) {
super.onScrolled(recyclerView, dx, dy)
val layoutManager = recyclerView.layoutManager
if (layoutManager is LinearLayoutManager && !mListViewModel.obsListData.value.isNullOrEmpty()) {
val firstVisiblePosition = layoutManager.findFirstVisibleItemPosition()
val readableDaysOffset = mListViewModel.getReadableDaysOffset(firstVisiblePosition)
val currentTimeFilter = mGameServerTestV2ViewModel?.getSelectedTimeFilterString(readableDaysOffset)
if (mSupremeSelectedTimeFilter == null && currentTimeFilter?.isNotEmpty() == true) {
if (mGameServerTestV2ViewModel?.selectedTimeFilterLiveData?.value != currentTimeFilter) {
NewFlatLogUtils.logGameTestDetailTimelineClick(
mTabFilterValue,
"自动定位",
currentTimeFilter
)
}
mGameServerTestV2ViewModel?.selectedTimeFilterLiveData?.value = currentTimeFilter
}
if (!mListViewModel.isLoadFirstPage) {
mBinding?.pullDownTipIv?.visibility = View.GONE
}
// 悬挂的文案
mBinding?.topDateContainer?.root?.visibility = View.VISIBLE
mBinding?.topDateContainer?.timeTv?.text =
mListViewModel?.getDayTextByPosition(firstVisiblePosition)
// 悬挂界面移动
val lp = mBinding?.topDateContainer?.root?.layoutParams as FrameLayout.LayoutParams
if (firstVisiblePosition != 0
&& mListViewModel?.getItemAtPosition(firstVisiblePosition + 1)?.time != null
) {
val bottom = layoutManager.findViewByPosition(firstVisiblePosition)?.bottom ?: 0
if (bottom <= (mBinding?.topDateContainer?.root?.height ?: 0)) {
lp.topMargin = bottom - (mBinding?.topDateContainer?.root?.height ?: 0)
} else {
lp.topMargin = 0
}
} else {
lp.topMargin = 0
}
mBinding?.topDateContainer?.root?.layoutParams = lp
scroll()
}
}
override fun onScrollStateChanged(recyclerView: RecyclerView, newState: Int) {
super.onScrollStateChanged(recyclerView, newState)
if (newState == RecyclerView.SCROLL_STATE_IDLE && !mSupremeSelectedTimeFilter.isNullOrEmpty()) {
mSupremeSelectedTimeFilter = null
}
if (newState == RecyclerView.SCROLL_STATE_DRAGGING) {
mSupremeSelectedTimeFilter = null
}
mScrollCalculatorHelper.onScrollStateChanged(newState)
}
})
}
private fun scroll() {
val firstVisibleItem = (mListRv.layoutManager as LinearLayoutManager).findFirstVisibleItemPosition()
val lastVisibleItem = (mListRv.layoutManager as LinearLayoutManager).findLastVisibleItemPosition()
mScrollCalculatorHelper.onScroll(firstVisibleItem, lastVisibleItem)
}
override fun provideListAdapter(): ListAdapter<*> {
val exposureSource =
if (requireArguments().getParcelable<ExposureSource>(EntranceConsts.KEY_EXPOSURE_SOURCE) != null) {
listOf<ExposureSource>(requireArguments().getParcelable(EntranceConsts.KEY_EXPOSURE_SOURCE)!!)
} else {
null
}
val position = requireArguments().getInt(EntranceConsts.KEY_POSITION)
return mAdapter ?: GameServerTestV2ListAdapter(
requireContext(),
mEntrance,
mGameServerTestV2ViewModel,
exposureSource,
position
).apply {
mAdapter = this
}
}
override fun getItemDecoration(): RecyclerView.ItemDecoration? = null
fun changeTimeFilter() {
if (::mScrollCalculatorHelper.isInitialized) {
mScrollCalculatorHelper.currentPlayer?.release()
}
NewFlatLogUtils.logGameTestDetailTimelineClick(
mTabFilterValue,
"手动点击",
mGameServerTestV2ViewModel?.selectedTimeFilterLiveData?.value ?: ""
)
mSupremeSelectedTimeFilter = mGameServerTestV2ViewModel?.getCurrentSelectedTimeFilter() ?: ""
scrollToTime(mSupremeSelectedTimeFilter!!)
}
fun changeCategoryFilter() {
if (::mScrollCalculatorHelper.isInitialized) {
mScrollCalculatorHelper.currentPlayer?.release()
}
onLoadRefresh()
NewFlatLogUtils.logGameTestDetailGameCategoryClick(
mTabFilterValue,
mGameServerTestV2ViewModel?.selectedCategoryFilter ?: "",
mGameServerTestV2ViewModel?.selectedTimeFilterLiveData?.value ?: "",
)
}
override fun onFragmentResume() {
resumeVideo()
DownloadManager.getInstance().addObserver(dataWatcher)
super.onFragmentResume()
}
override fun onFragmentPause() {
pauseVideo()
DownloadManager.getInstance().removeObserver(dataWatcher)
super.onFragmentPause()
val firstVisibleItemPosition = mLayoutManager?.findFirstVisibleItemPosition() ?: -1
if (firstVisibleItemPosition >= 0) {
val testTime = mListViewModel.obsListData.value?.safelyGetInRelease(firstVisibleItemPosition)?.testTime ?: 0
val stayTime = (System.currentTimeMillis() - startPageTime) / 1000
NewFlatLogUtils.logGameTestDetailView(
mTabFilterValue,
stayTime,
testTime,
mGameServerTestV2ViewModel?.selectedTimeFilterLiveData?.value ?: ""
)
}
}
//下载被删除事件
@Subscribe(threadMode = ThreadMode.MAIN)
fun onEventMainThread(status: EBDownloadStatus) {
DownloadManager.getInstance().removePlatform(status.name, status.platform)
if (status.status == "delete") {
mListViewModel?.locationMap?.get(status.packageName)?.let {
for (location in it) {
mListViewModel?.obsListData?.value?.safelyGetInRelease(location)?.game?.getEntryMap()
?.remove(status.platform)
mAdapter?.notifyItemChanged(location)
}
}
}
}
private fun pauseVideo() {
if (mScrollCalculatorHelper.currentPosition >= 0) {
mScrollCalculatorHelper.currentPlayer?.resetDetailMask()
mScrollCalculatorHelper.currentPlayer?.onVideoPause()
val currentPosition = mScrollCalculatorHelper.currentPlayer?.getCurrentPosition() ?: 0L
val topVideo =
mListViewModel.obsListData.value?.safelyGetInRelease(mScrollCalculatorHelper.currentPosition)?.game?.topVideo
if (topVideo != null) {
ScrollCalculatorHelper.savePlaySchedule(
MD5Utils.getContentMD5(topVideo.url),
currentPosition
)
}
}
}
private fun resumeVideo() {
if (mScrollCalculatorHelper.currentPlayer != null) {
val topVideo =
mListViewModel.obsListData.value?.safelyGetInRelease(mScrollCalculatorHelper.currentPosition)?.game?.topVideo
if (topVideo != null) {
val position =
ScrollCalculatorHelper.getPlaySchedule(MD5Utils.getContentMD5(topVideo.url))
//这里必须要延迟操作,否则会白屏
mBaseHandler.postDelayed({
if (position != 0L) {
mScrollCalculatorHelper.currentPlayer?.seekTo(position)
mScrollCalculatorHelper.currentPlayer?.onVideoResume(false)
val topVideoVoiceStatus =
SPUtils.getBoolean(Constants.SP_VIDEO_PLAY_MUTE, true)
if (topVideoVoiceStatus) {
mScrollCalculatorHelper.currentPlayer?.mute()
} else {
mScrollCalculatorHelper.currentPlayer?.unMute()
}
} else {
mScrollCalculatorHelper.currentPlayer?.release()
}
}, 50)
}
}
}
override fun onChanged(ts: MutableList<GameServerTestV2ListViewModel.ItemData>?) {
super.onChanged(ts)
if (!ts.isNullOrEmpty() && mListViewModel.isLoadFirstPage) {
scrollToTime(GameServerTestV2ViewModel.TimeFilter.TODAY.value)
mListRv.postDelayed({
scroll()
mScrollCalculatorHelper.onScrollStateChanged(RecyclerView.SCROLL_STATE_IDLE)
}, 200)
}
}
private fun scrollToTime(timeFilter: String) {
val positionToScroll = mListViewModel!!.getPositionByTimeFilter(timeFilter)
if (positionToScroll < 0) return
mLayoutManager.scrollToPositionWithOffset(positionToScroll, 0)
mListRv.post {
mLayoutManager.scrollToPositionWithOffset(positionToScroll, 0)
if (mListViewModel.isLoadFirstPage) {
mListRv.post {
val firstVisibleItemPosition = mLayoutManager.findFirstVisibleItemPosition()
mBinding?.pullDownTipIv?.goneIf(firstVisibleItemPosition <= 0)
mListViewModel.isLoadFirstPage = false
}
}
}
}
override fun onLoadError() {
super.onLoadError()
mBinding?.topDateContainer?.root?.visibility = View.GONE
mBinding?.pullDownTipIv?.visibility = View.GONE
}
override fun onLoadEmpty() {
super.onLoadEmpty()
mBinding?.topDateContainer?.root?.visibility = View.GONE
mBinding?.pullDownTipIv?.visibility = View.GONE
}
override fun onDestroy() {
super.onDestroy()
if (::mScrollCalculatorHelper.isInitialized) {
mScrollCalculatorHelper.currentPlayer?.release()
}
}
}

View File

@ -0,0 +1,332 @@
package com.gh.gamecenter.servers.gametest2
import android.app.Application
import androidx.collection.ArrayMap
import androidx.collection.arrayMapOf
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.alibaba.android.arouter.launcher.ARouter
import com.gh.common.filter.RegionSettingHelper
import com.gh.gamecenter.common.baselist.ListViewModel
import com.gh.gamecenter.common.baselist.LoadStatus
import com.gh.gamecenter.common.baselist.LoadType
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.common.retrofit.Response
import com.gh.gamecenter.common.utils.observableToMain
import com.gh.gamecenter.common.utils.safelyGetInRelease
import com.gh.gamecenter.core.provider.IHandleGameResponseProvider
import com.gh.gamecenter.core.utils.TimeUtils
import com.gh.gamecenter.core.utils.UrlFilterUtils
import com.gh.gamecenter.entity.GameServerTestV2Entity
import com.gh.gamecenter.entity.ServerTestEntity
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.retrofit.RetrofitManager
import io.reactivex.Observable
import retrofit2.HttpException
import java.text.SimpleDateFormat
import java.util.*
class GameServerTestV2ListViewModel(
application: Application,
private val mGameServerTestV2ViewModel: GameServerTestV2ViewModel?
) : ListViewModel<ServerTestEntity.SliceData, GameServerTestV2ListViewModel.ItemData>(application) {
var isLoadFirstPage = false
val locationMap: ArrayMap<String, ArrayList<Int>> = arrayMapOf()
private val mApi = RetrofitManager.getInstance().api
private val mTimePositionArrayMap = ArrayMap<String, Int>()
private val mCurrentPreviousAndNextWeeks = TimeUtils.getCurrentPreviousAndNextWeek()
private val mTodayYesterdayAndTomorrowDate = TimeUtils.getTodayYesterdayAndTomorrow("MM.dd")
override fun provideDataObservable(page: Int): Observable<MutableList<ServerTestEntity.SliceData>>? {
return null
}
override fun load(loadType: LoadType?) {
isLoadFirstPage = true
mListLiveData.value = null
mLoadStatusLiveData.postValue(LoadStatus.INIT_LOADING)
val tabFilter = mGameServerTestV2ViewModel?.tabFilter?.value
var categoryFilter = mGameServerTestV2ViewModel?.getCurrentSelectedCategoryFilterValue()?.value
//如果选择全部类型,则传空值
if (categoryFilter == GameServerTestV2ViewModel.GameCategory.ALL.value) {
categoryFilter = ""
}
val filterQuery = UrlFilterUtils.getFilterQuery(
"tab",
tabFilter,
"category",
categoryFilter,
)
mApi.getServerTestV2(filterQuery)
.compose(observableToMain())
.subscribe(object : Response<GameServerTestV2Entity>() {
override fun onResponse(response: GameServerTestV2Entity?) {
super.onResponse(response)
response?.let {
var index = 0
while (index < it.data.size) {
val slide = it.data[index]
// 推荐tab需要过滤掉既没有游戏大图也没有顶部视频的游戏
if (mGameServerTestV2ViewModel?.tabFilter == GameServerTestV2ViewModel.TestFilter.RECOMMEND) {
filterGameWithoutVideoAndImage(slide.gameList)
}
slide.gameList = RegionSettingHelper.filterGame(slide.gameList)
// 针对游戏的一些操作(过滤隐藏游戏过滤隐藏APK增加下载数据)
val handleGameResponse =
ARouter.getInstance().build(RouteConsts.provider.handleGameResponse)
.navigation() as? IHandleGameResponseProvider
if (handleGameResponse != null) {
slide.gameList = handleGameResponse.handleGameResponse(
slide.gameList,
mEntrance
) as ArrayList<GameEntity>
}
//对应日期下没有游戏时,则跳过不显示对应日期
if (slide.gameList.isEmpty()) {
it.data.remove(slide)
}
index++
}
loadStatusControl(it)
mListLiveData.postValue(it.data)
}
}
override fun onFailure(e: HttpException?) {
super.onFailure(e)
mLoadStatusLiveData.postValue(LoadStatus.INIT_FAILED)
}
})
}
private fun loadStatusControl(entity: GameServerTestV2Entity) {
when {
entity.data.isEmpty() -> {
mLoadStatusLiveData.postValue(LoadStatus.INIT_EMPTY)
}
entity.data.isEmpty() -> {
mLoadStatusLiveData.postValue(LoadStatus.INIT_OVER)
}
else -> {
mLoadStatusLiveData.postValue(LoadStatus.INIT_LOADED)
}
}
}
override fun mergeResultLiveData() {
mResultLiveData.addSource(mListLiveData) {
transformData()
}
}
private fun transformData() {
val list = arrayListOf<ItemData>()
val subList = arrayListOf<ItemData>()
mTimePositionArrayMap.clear()
for (slice in mListLiveData.value ?: listOf()) {
subList.clear()
var testTimeInHumanReadableFormat: String
val sdf = SimpleDateFormat("MM.dd", Locale.CHINA)
val day = mTodayYesterdayAndTomorrowDate.find { it.first == sdf.format(slice.testTime * 1000) }
if (day != null && day.second in -1..1) {
testTimeInHumanReadableFormat = when (day.second) {
-1 -> "昨天"
0 -> "今天"
else -> "明天"
}
testTimeInHumanReadableFormat = "${sdf.format(slice.testTime * 1000)} $testTimeInHumanReadableFormat"
} else {
testTimeInHumanReadableFormat = sdf.format(slice.testTime * 1000)
val find = mCurrentPreviousAndNextWeeks.find { it.first == testTimeInHumanReadableFormat }
if (find != null) {
testTimeInHumanReadableFormat = "$testTimeInHumanReadableFormat ${find.second}"
}
}
val readableDaysOffset = when (slice.timeType) {
"recent" -> GameServerTestV2ViewModel.TimeFilter.PAST_DAY.value
"future" -> GameServerTestV2ViewModel.TimeFilter.UPCOMING_DAY.value
else -> GameServerTestV2ViewModel.TimeFilter.TODAY.value
}
subList.add(
ItemData(
time = testTimeInHumanReadableFormat,
testTime = slice.testTime,
readableDaysOffset = readableDaysOffset
)
)
for ((index, game) in slice.gameList.withIndex()) {
game.serverType = game.test?.type ?: game.serverType
var brief: String
//开测时间优先显示为 “昨天、今天、明天、周X、上周X、下周X”超过“上周一-下周日”范围则显示“月份-日期”
if (day != null && day.second in -1..1) {
brief = when (day.second) {
-1 -> "昨天"
0 -> "今天"
else -> "明天"
}
} else {
brief = sdf.format(slice.testTime * 1000)
val find = mCurrentPreviousAndNextWeeks.find { it.first == brief }
if (find != null) {
brief = find.second
}
}
val isBigImage = mGameServerTestV2ViewModel?.tabFilter == GameServerTestV2ViewModel.TestFilter.RECOMMEND
&& (readableDaysOffset == GameServerTestV2ViewModel.TimeFilter.TODAY.value
|| readableDaysOffset == GameServerTestV2ViewModel.TimeFilter.UPCOMING_DAY.value)
game.brief = if (isBigImage) {
game.recommendText
} else {
val eventType = if (game.eventType == "test") "开启测试" else "首发上线"
"$brief ${TimeUtils.getFormatTime(game.time?.time ?: 0L, "HH:mm")} $eventType"
}
game.sequence = index
game.testTime = sdf.format(slice.testTime * 1000)
subList.add(
ItemData(
game = game,
testTime = slice.testTime,
readableDaysOffset = readableDaysOffset,
isTheLastOfTheLatestConsecutiveGame = index == slice.gameList.lastIndex,
isBigImage = isBigImage
)
)
}
if (subList.size > 1) {
val isCurrentDaysOffsetExist = mTimePositionArrayMap.getOrDefault(readableDaysOffset, 999) != 999
if (!isCurrentDaysOffsetExist) {
mTimePositionArrayMap[readableDaysOffset] = list.size
}
list.addAll(subList)
}
}
initLocationMap(list)
mResultLiveData.postValue(list)
}
private fun filterGameWithoutVideoAndImage(list: ArrayList<GameEntity>) {
var i = 0
while (i < list.size) {
val gameEntity = list[i]
if (gameEntity.topVideo == null && gameEntity.homeSetting.image.isEmpty()) {
list.removeAt(i)
i--
}
i++
}
}
private fun initLocationMap(itemList: ArrayList<ItemData>) {
locationMap.clear()
var list: ArrayList<Int>?
var i = 0
val size: Int = itemList.size
while (i < size) {
itemList[i].game?.let { gameEntity ->
if (gameEntity.getApk().size != 0) {
for (apk in gameEntity.getApk()) {
list = locationMap[apk.packageName]
if (list == null) {
list = ArrayList()
locationMap[apk.packageName] = list
}
list?.add(i)
}
}
}
i++
}
}
fun getReadableDaysOffset(position: Int): String {
return mResultLiveData.value?.safelyGetInRelease(position)?.readableDaysOffset ?: ""
}
fun getDayTextByPosition(position: Int): String {
var dayText = ""
val dataList = mResultLiveData.value
dataList?.let {
for ((index, value) in dataList.withIndex()) {
if (value.time != null) {
dayText = value.time ?: ""
}
if (index == position) {
return dayText
}
}
}
return dayText
}
fun getItemAtPosition(position: Int): ItemData? {
if (position < (mResultLiveData?.value?.size ?: 0)) {
return mResultLiveData.value?.get(position)
}
return null
}
fun getPositionByTimeFilter(timeFilter: String): Int {
val itemDataList = mResultLiveData.value ?: arrayListOf()
var position = mTimePositionArrayMap.getOrDefault(timeFilter, -1)
if (position >= 0) return position
val recentCount =
itemDataList.count { it.readableDaysOffset == GameServerTestV2ViewModel.TimeFilter.PAST_DAY.value }
val todayCount =
itemDataList.count { it.readableDaysOffset == GameServerTestV2ViewModel.TimeFilter.TODAY.value }
when (timeFilter) {
GameServerTestV2ViewModel.TimeFilter.PAST_DAY.value -> {
position = mTimePositionArrayMap.getOrDefault(GameServerTestV2ViewModel.TimeFilter.TODAY.value, -1)
if (position >= 0) return position
position =
mTimePositionArrayMap.getOrDefault(GameServerTestV2ViewModel.TimeFilter.UPCOMING_DAY.value, -1)
if (position >= 0) return position
}
GameServerTestV2ViewModel.TimeFilter.TODAY.value -> {
position =
mTimePositionArrayMap.getOrDefault(GameServerTestV2ViewModel.TimeFilter.UPCOMING_DAY.value, -1)
if (position >= 0) return position
position =
mTimePositionArrayMap.getOrDefault(GameServerTestV2ViewModel.TimeFilter.PAST_DAY.value, -1)
if (position >= 0) return recentCount - 1
}
GameServerTestV2ViewModel.TimeFilter.UPCOMING_DAY.value -> {
position = mTimePositionArrayMap.getOrDefault(GameServerTestV2ViewModel.TimeFilter.TODAY.value, -1)
if (position >= 0) return recentCount + todayCount - 1
position =
mTimePositionArrayMap.getOrDefault(GameServerTestV2ViewModel.TimeFilter.PAST_DAY.value, -1)
if (position >= 0) recentCount - 1
}
}
return -1
}
class ItemData(
var time: String? = null,
var game: GameEntity? = null,
var readableDaysOffset: String = "",
var testTime: Long = 0,
var isTheLastOfTheLatestConsecutiveGame: Boolean = false,
var isBigImage: Boolean = false
)
class Factory(
private val mApplication: Application,
private val mGameServerTestV2ViewModel: GameServerTestV2ViewModel?
) : ViewModelProvider.NewInstanceFactory() {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return GameServerTestV2ListViewModel(mApplication, mGameServerTestV2ViewModel) as T
}
}
}

View File

@ -0,0 +1,82 @@
package com.gh.gamecenter.servers.gametest2
import android.app.Application
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
class GameServerTestV2ViewModel(application: Application) : AndroidViewModel(application) {
var tabFilter = TestFilter.RECOMMEND
val timeFilterList = arrayListOf(RECENT_GAME, TODAY_GAME, FUTURE_GAME)
val categoryFilterList = arrayListOf("全部类型", "单机游戏", "网络游戏", "福利游戏", "国际服游戏")
var selectedCategoryFilter: String = categoryFilterList[0]
var selectedTimeFilterLiveData = MutableLiveData(timeFilterList[1])
fun getCurrentSelectedCategoryFilterValue(): GameCategory {
return when (selectedCategoryFilter) {
"全部类型" -> GameCategory.ALL
"单机游戏" -> GameCategory.LOCAL
"网络游戏" -> GameCategory.ONLINE
"福利游戏" -> GameCategory.WELFARE
"国际服游戏" -> GameCategory.GJONLINE
else -> GameCategory.ALL
}
}
fun getSelectedTimeFilterString(dayFilter: String): String {
return when (dayFilter) {
TimeFilter.PAST_DAY.value -> RECENT_GAME
TimeFilter.TODAY.value -> TODAY_GAME
TimeFilter.UPCOMING_DAY.value -> FUTURE_GAME
else -> TODAY_GAME
}
}
fun getCurrentSelectedTimeFilter(): String {
return when (selectedTimeFilterLiveData.value) {
RECENT_GAME -> TimeFilter.PAST_DAY.value
TODAY_GAME -> TimeFilter.TODAY.value
FUTURE_GAME -> TimeFilter.UPCOMING_DAY.value
else -> TimeFilter.TODAY.value
}
}
fun setSelectedTimeFilter(filter: String?) {
if (filter.isNullOrEmpty()) return
selectedTimeFilterLiveData.value = filter
}
enum class TestFilter(val value: String) {
RECOMMEND("recommend"),
ALL("all"),
}
enum class TimeFilter(val value: String) {
PAST_DAY("recent"),
TODAY("today"),
UPCOMING_DAY("future")
}
enum class GameCategory(val value: String) {
ALL("all"),
LOCAL("local"),
ONLINE("online"),
WELFARE("welfare"),
GJONLINE("gjonline"),
}
companion object {
const val RECENT_GAME = "近期新游"
const val TODAY_GAME = "今日新游"
const val FUTURE_GAME = "即将开测"
}
class Factory(private val mApplication: Application) :
ViewModelProvider.NewInstanceFactory() {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return GameServerTestV2ViewModel(mApplication) as T
}
}
}

View File

@ -214,7 +214,7 @@ class DetailPlayerView @JvmOverloads constructor(context: Context, attrs: Attrib
mBinding.gameIconView.displayGameIcon(
videoEntity.game?.rawIcon
?: videoEntity.gameIcon, videoEntity.game?.iconSubscript
?: videoEntity.gameIcon, videoEntity.game?.iconSubscript, videoEntity.game?.iconFloat
)
ImageUtils.display(mBinding.userIconIv, videoEntity.user.icon)
if (videoEntity.user.border.isNotEmpty()) {

View File

@ -74,7 +74,7 @@ class GameVideoActivity : ToolBarActivity() {
if (it.status == Status.SUCCESS) {
mBinding.gameIcon.displayGameIcon(
it.data?.game?.getIcon()
?: it.data?.gameIcon, it.data?.game?.iconSubscript
?: it.data?.gameIcon, it.data?.game?.iconSubscript, it.data?.game?.iconFloat
)
mBinding.gameName.text = it.data?.game?.name
mBinding.likeCount.text = NumberUtils.transSimpleCount(it.data?.likeCount ?: 0)

View File

@ -10,6 +10,7 @@ import com.gh.download.DownloadManager
import com.gh.gamecenter.R
import com.gh.gamecenter.common.baselist.DiffUtilAdapter
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.entity.IconFloat
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.view.GridSpacingItemColorDecoration
import com.gh.gamecenter.core.utils.ToastUtils
@ -115,9 +116,15 @@ class HomeRecentVGameAdapter(context: Context) : DiffUtilAdapter<VGameItemData>(
fun bindView(entity: VGameItemData) {
if (mBinding.gameIconIv.getTag(R.string.app_name) != entity.downloadEntity.packageName) {
val iconFloat = IconFloat(
entity.downloadEntity.getMetaExtra(Constants.GAME_ICON_FLOAT_TOP_TEXT),
entity.downloadEntity.getMetaExtra(Constants.GAME_ICON_FLOAT_TOP_COLOR),
entity.downloadEntity.getMetaExtra(Constants.GAME_ICON_FLOAT_BOTTOM_TEXT)
)
mBinding.gameIconIv.displayGameIcon(
entity.downloadEntity.getMetaExtra(Constants.RAW_GAME_ICON),
entity.downloadEntity.getMetaExtra(Constants.GAME_ICON_SUBSCRIPT)
entity.downloadEntity.getMetaExtra(Constants.GAME_ICON_SUBSCRIPT),
iconFloat
)
mBinding.gameIconIv.setTag(R.string.app_name, entity.downloadEntity.packageName)
}

View File

@ -799,6 +799,20 @@ object VHelper {
updateEntity.iconSubscript
)
originDownloadEntity.addMetaExtra(Constants.APK_MD5, updateEntity.md5)
if (updateEntity.iconFloat != null) {
originDownloadEntity.addMetaExtra(
Constants.GAME_ICON_FLOAT_TOP_TEXT,
updateEntity.iconFloat?.upperLeftText
)
originDownloadEntity.addMetaExtra(
Constants.GAME_ICON_FLOAT_TOP_COLOR,
updateEntity.iconFloat?.upperLeftColor
)
originDownloadEntity.addMetaExtra(
Constants.GAME_ICON_FLOAT_BOTTOM_TEXT,
updateEntity.iconFloat?.bottomText
)
}
PackageRepository.removeUpdate(updateEntity.id, true)
}

View File

@ -87,15 +87,9 @@ class VSpaceDialogFragment : BaseDraggableDialogFragment() {
}
}
val spanBuilder = SpannableStringBuilder()
.append("畅玩是一种更灵活、轻便的游戏方式\n")
.append("下载")
.color(R.color.text_subtitle.toColor(requireContext())) { bold { append(" 畅玩助手服务组件 ") } }
.append("即可快速畅玩游戏~")
mBinding.downloadBtn.text = "下载畅玩助手服务组件"
mBinding.downloadBtn.buttonStyle = DownloadButton.ButtonStyle.NORMAL
mBinding.descTv.text = spanBuilder
mBinding.descTv.text = "监测到您未安装畅玩64位组件\n点击下载即可体验急速畅玩~"
mBinding.privacyPolicyTv.setOnClickListener {
NewFlatLogUtils.logHaloFunEvent("halo_fun_download_dialog_privacy_click")
DirectUtils.directToWebView(requireContext(), Constants.SMOOTH_GAME_PRIVACY_POLICY_ADDRESS)

View File

@ -276,10 +276,14 @@ class RealNameInfoFragment : ToolbarFragment() {
* 屏幕高度小于等于 1080 (16:9) 的设备看作无法显示完整内容
*/
private fun isScreenUnableToShowAllTheContent(): Boolean {
return DisplayUtils.getScreenHeight() <= 1920
return DisplayUtils.getScreenHeight() <= 1920 || DisplayUtils.isUltraShortScreen()
}
/**
* 使用更紧凑的布局,避免一些内容不能显示,导致不能用
*/
private fun changeToCompatView() {
mBinding.infoContainer.setPadding(20F.dip2px(), 0, 20F.dip2px(), 0)
mBinding.bodyTv.setLineSpacing(0F, 1F)
mBinding.hintTv.setLineSpacing(0F, 1F)
mBinding.manualHintTv.setLineSpacing(0F, 1F)

Binary file not shown.

After

Width:  |  Height:  |  Size: 791 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

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