Compare commits

..

50 Commits

Author SHA1 Message Date
6b694efde7 fix:GHZS-4715,GHZS-4696,GHZS-4668,GHZS-4713,GHZS-4712,GHZS-4665 https://jira.shanqu.cc/browse/GHZS-3956 2024-02-02 13:57:32 +08:00
acf19645bd Merge branch 'chen/202401/fix-custom-page-ui2' into 'feat/GHZS-3956'
fix:GHZS-4696,GHZS-4684,GHZS-4685,GHZS-4688,GHZS-4668 https://jira.shanqu.cc/browse/GHZS-3956

See merge request halo/android/assistant-android!1534
2024-01-31 18:05:09 +08:00
0122a66bfe fix:GHZS-4696,GHZS-4684,GHZS-4685,GHZS-4688,GHZS-4668 https://jira.shanqu.cc/browse/GHZS-3956 2024-01-31 18:03:44 +08:00
a0a72b5356 fix: APP内容配置重构-客户端-页面:多tab导航页-0130测试-客户端 https://jira.shanqu.cc/browse/GHZS-4701 2024-01-31 17:49:40 +08:00
a4d12fd118 fix: 首次启动跳转-0131测试 https://jira.shanqu.cc/browse/GHZS-4706 2024-01-31 15:32:20 +08:00
db7452aa57 fix: APP内容配置重构-客户端-页面:多tab导航页-0130测试-客户端 https://jira.shanqu.cc/browse/GHZS-4701 2024-01-31 14:04:20 +08:00
895594f7ec fix: APP内容配置重构-其他组件:下拉推送—客户端 (修复下拉推送背景圆角出现锯齿的问题) https://jira.shanqu.cc/browse/GHZS-4070 2024-01-30 17:26:45 +08:00
7d29b1904e fix: 处理合并冲突 2024-01-30 14:15:28 +08:00
246b6666ad fix:GHZS-4683,GHZS-4687,GHZS-4680,GHZS-4671 https://jira.shanqu.cc/browse/GHZS-3956 2024-01-30 11:54:21 +08:00
ed062e38e0 优化轮播图轮播逻辑:页面滚动或者轮播图不可见时,停止轮播 GHZS-3956 2024-01-30 11:54:21 +08:00
af4ee349a9 fix:自定义页面测试bug:GHZS-4647,GHZS-4643,GHZS-4605 https://jira.shanqu.cc/projects/GHZS/issues/GHZS-4647?filter=myopenissues 2024-01-30 11:54:21 +08:00
3abba92826 fix: APP内容配置重构-页面:多tab导航页—客户端(修复切换深色模式出现的界面异常) https://jira.shanqu.cc/browse/GHZS-4080 2024-01-30 11:54:21 +08:00
4ceb25e407 fix: APP内容配置重构-底部tab—客户端(修改通用跳转命名,底部tab部分页面改为懒加载) https://jira.shanqu.cc/browse/GHZS-4025 2024-01-30 11:54:21 +08:00
40896d2ebf feat: APP内容配置重构-埋点—客户端2(补充曝光数据1) https://jira.shanqu.cc/browse/GHZS-4559 2024-01-30 11:54:21 +08:00
4b258ffc8a fix:长列表式,点击换一批crash 2024-01-30 11:54:21 +08:00
3b43b25e71 fix:参数缺失 2024-01-30 11:54:21 +08:00
0a4424495d fix:APP内容配置重构-客户端-组件:专题合集-轮播图-01/24测试-客户端 https://jira.shanqu.cc/projects/GHZS/issues/GHZS-4653?filter=myopenissues 2024-01-30 11:54:21 +08:00
5435ea33b4 fix: APP内容配置重构-刷新轮换—客户端(修复刷新轮换游戏全部被屏蔽时显示错误页数的问题) https://jira.shanqu.cc/browse/GHZS-4257 2024-01-30 11:54:21 +08:00
68a68688b8 feat: APP内容配置重构-埋点—客户端2 https://jira.shanqu.cc/browse/GHZS-4559 2024-01-30 11:54:21 +08:00
9ece6506c6 fix:APP内容配置重构-客户端-组件:游戏专题-光环游戏-0120测试—客户端 https://jira.shanqu.cc/projects/GHZS/issues/GHZS-4608?filter=myopenissues 2024-01-30 11:53:36 +08:00
52497f705f fix: 修复首页闪退问题 https://jira.shanqu.cc/browse/GHZS-3956 2024-01-30 11:53:36 +08:00
bb1a00f36a feat: APP内容配置重构-附属需求:弹窗顺序 https://jira.shanqu.cc/browse/GHZS-4086 2024-01-30 11:53:36 +08:00
fb1553bfb0 feat: APP内容配置重构-附属需求:首次启动跳转 https://jira.shanqu.cc/browse/GHZS-4085 2024-01-30 11:53:36 +08:00
9b77eb584d feat: APP内容配置重构-附属需求:弹窗顺序 https://jira.shanqu.cc/browse/GHZS-4086 2024-01-30 11:53:36 +08:00
24af66d271 fix:APP内容配置重构-客户端-组件:游戏专题-QQ小游戏-0120测试-客户端 https://jira.shanqu.cc/browse/GHZS-4607 2024-01-30 11:53:36 +08:00
e48be196f5 fix: APP内容配置重构-换一批—客户端(修复点击换一批后功能失效的问题) https://jira.shanqu.cc/browse/GHZS-4256 2024-01-30 11:53:36 +08:00
8eb2da9d8d feat:自定义页面曝光埋点:https://jira.shanqu.cc/projects/GHZS/issues/GHZS-4397?filter=myopenissues 2024-01-30 11:53:36 +08:00
12b1f4c056 feat: APP内容配置重构-自定义页面下载按钮—客户端 https://jira.shanqu.cc/browse/GHZS-4255 2024-01-30 11:53:36 +08:00
2ee771572c fix: 补充自定义页面轮播发现页卡片获取游戏逻辑 https://jira.shanqu.cc/browse/GHZS-4596 2024-01-30 11:53:36 +08:00
7b94818b42 fix: 0119测试-客户端(2) https://jira.shanqu.cc/browse/GHZS-4596 2024-01-30 11:53:36 +08:00
1f4f2a018b feat:APP内容配置重构-客户端-页面:自定义页面-01/19测试-客户端 https://jira.shanqu.cc/browse/GHZS-4601 2024-01-30 11:53:36 +08:00
6a5ffa19f1 feat: APP内容配置重构-附属需求:弹窗顺序 https://jira.shanqu.cc/browse/GHZS-4086 2024-01-30 11:53:36 +08:00
861a8e0017 fix: APP内容配置重构-其他组件:搜索栏—客户端(修复点击搜索栏无法跳转的问题) https://jira.shanqu.cc/browse/GHZS-4073 2024-01-30 11:53:36 +08:00
8abe6a9fff fix: APP内容配置重构-其他组件:下拉推送—客户端 (修复下拉推送UI显示问题) https://jira.shanqu.cc/browse/GHZS-4070 2024-01-30 11:53:36 +08:00
b5d2f01cd1 fix:修复折叠滑动大图,图标矩阵crash https://jira.shanqu.cc/browse/GHZS-4076 2024-01-30 11:53:36 +08:00
22f98fa7eb fix:光环APP】APP内容配置重构-客户端-页面:自定义页面:修复crash https://jira.shanqu.cc/browse/GHZS-4076 2024-01-30 11:53:36 +08:00
231bad54ab fix: 修复懒加载问题 2024-01-30 11:53:36 +08:00
56cbc1968b fix: APP内容配置重构-底部tab—客户端(关闭ViewPager2离屏加载,设置缓存数量) https://jira.shanqu.cc/browse/GHZS-4025 2024-01-30 11:53:31 +08:00
de404d3a5e fix: APP内容配置重构-底部tab—客户端(修复视频Tab显示问题) https://jira.shanqu.cc/browse/GHZS-4025 2024-01-30 11:53:31 +08:00
b913724aae fix: APP内容配置重构-其他组件:下拉推送—客户端(修复首页为自定义页面时下拉推送搜索栏没有更新背景的问题) https://jira.shanqu.cc/browse/GHZS-4070 2024-01-30 11:53:31 +08:00
9d401253d2 feat:【光环APP】APP内容配置重构-客户端-页面:自定义页面 https://jira.shanqu.cc/browse/GHZS-4076 2024-01-30 11:53:31 +08:00
a268817fa6 feat:APP内容配置重构-页面:自定义页面—客户端 https://jira.shanqu.cc/projects/GHZS/issues/GHZS-4077?filter=myopenissues 2024-01-30 11:53:31 +08:00
1d89a49609 ci 2024-01-30 11:53:31 +08:00
9d91796548 feat: APP内容配置重构-换一批—客户端 https://jira.shanqu.cc/browse/GHZS-4256
feat: APP内容配置重构-刷新轮换—客户端 https://jira.shanqu.cc/browse/GHZS-4257
feat: APP内容配置重构-其他组件:搜索栏—客户端 https://jira.shanqu.cc/browse/GHZS-4073
feat: APP内容配置重构-页面:多tab导航页—客户端 https://jira.shanqu.cc/browse/GHZS-4080
feat: APP内容配置重构-其他组件:下拉推送—客户端 https://jira.shanqu.cc/browse/GHZS-4070
feat: APP内容配置重构-页面:多tab导航页—客户端 https://jira.shanqu.cc/browse/GHZS-4080
feat: APP内容配置重构-底部tab—客户端 https://jira.shanqu.cc/browse/GHZS-4025
2024-01-30 11:53:31 +08:00
907b5442e0 对接通用内容合集数据
处理折叠滑动大图气泡动画
2024-01-30 11:53:31 +08:00
2711eaffda feat:APP内容配置重构-页面:自定义页面—客户端... 2024-01-30 11:53:31 +08:00
9f10ffa63d feat: APP内容配置重构-附属需求:弹窗顺序 https://jira.shanqu.cc/browse/GHZS-4086 2024-01-30 11:53:31 +08:00
adfe2766f8 fix: 处理代码冲突 2024-01-30 11:52:48 +08:00
39dd7e463e feat: 移除无用的游戏名后缀字段
Signed-off-by: chenjuntao <chenjuntao@ghzhushou.com>
2024-01-30 11:52:48 +08:00
869e2364e3 feat: 移除 GameEntity 无用的字段和方法,移除 Config 的一键修复相关功能 https://jira.shanqu.cc/browse/GHZS-4274 2024-01-30 11:52:48 +08:00
2463 changed files with 54721 additions and 75327 deletions

4
.gitignore vendored
View File

@ -9,6 +9,4 @@ build/
release-app/
test-app/
scripts/apk-channel/
app/src/test/java/com/gh/gamecenter
app/src/main/assets-debug/
app/src/main/assets-release/
app/src/test/java/com/gh/gamecenter

View File

@ -71,15 +71,15 @@ android_build:
exit_codes: 137
only:
- dev
- release
- pack/update_sentry_plugin_cache
- dev-5.33.0
- feat/GHZS-3956
# 代码检查
sonarqube_analysis:
tags:
- offline-test
stage: build&analyze
image: hub.shanqu.cc/library/sonar-scanner-cli:latest
image: sonarsource/sonar-scanner-cli:latest
dependencies: [] #禁止传递来的artifact
script:
## 获取项目的一级组和二级组和项目名作为projectKey例如projectKey=platform-backend-eci-monitor
@ -103,7 +103,8 @@ sonarqube_analysis:
exit_codes: 137
only:
- dev
- release
- dev-5.33.0
- feat/GHZS-3956
## 发送简易检测结果报告
send_sonar_report:
@ -121,16 +122,14 @@ send_sonar_report:
exit_codes: 137
only:
- dev
- release
- dev-5.33.0
- feat/GHZS-3956
oss-upload&send-email:
tags:
- sysadm-devops
stage: oss-upload&send-email
image: hub.shanqu.cc/devops/android-apk-oss-upload:latest
id_tokens:
VAULT_ID_TOKEN:
aud: https://vault.shanqu.cc
variables:
GIT_STRATEGY: none
VAULT_ADDR: https://vault.shanqu.cc # 固定值
@ -149,7 +148,6 @@ oss-upload&send-email:
artifacts: true
script:
### 绑定上传参数 ###
- export OSS_PATH="release/dev/${CI_PROJECT_NAME}/$(date "+%Y/%m/%d")"
### 开启上传 ###
- /usr/local/bin/python /upload.py
@ -157,5 +155,5 @@ oss-upload&send-email:
- /usr/local/bin/python /ci-android-mail-jira-comment.py
only:
- dev
- release
- pack/update_sentry_plugin_cache
- dev-5.33.0
- feat/GHZS-3956

6
.gitmodules vendored
View File

@ -5,9 +5,9 @@
[submodule "vspace-bridge"]
path = vspace-bridge
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 = ../../../halo/android/assistant-android-mock.git
[submodule "ndownload"]
path = ndownload
url = ../../../android/ndownload.git
[submodule "vasdk"]
path = vasdk
url = ../../../sdg/android/vasdk.git

View File

@ -44,4 +44,5 @@
### 混淆配置
* 本项目使用了微信的 [AndResGuard](https://github.com/shwenzhang/AndResGuard) 作为资源混淆压缩方案,新增需要使用 `getIdentifier` 获取的资源文件时需要添加至白名单
* 本项目默认使用 R8 作为混淆工具,往 proguard-rules.txt 添加 proguard 新配置项时请检查可用性(如语法等)

View File

@ -3,6 +3,7 @@ apply plugin: 'com.android.application'
apply plugin: 'kotlin-android' // kotlin
apply plugin: 'kotlin-parcelize'
apply plugin: 'kotlin-kapt'
apply plugin: 'AndResGuard'
import groovy.xml.XmlUtil
@ -22,8 +23,6 @@ android {
}
compileOptions {
coreLibraryDesugaringEnabled true
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
@ -74,7 +73,7 @@ android {
versionName rootProject.ext.versionName
applicationId rootProject.ext.applicationId
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt', 'proguard-fresco.txt', rootProject.ext.va_proguard_rules
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.txt', 'proguard-fresco.txt'
String CORE_EVENT_GAME_CATEGORY = ""
@ -101,14 +100,10 @@ android {
buildConfigField "String", "NEW_API_HOST", "\"${NEW_API_HOST}\""
buildConfigField "String", "LOG_HUB_PROJECT", "\"${LOG_HUB_PROJECT}\""
buildConfigField "String", "VAPI_HOST", "\"${VAPI_HOST}\""
buildConfigField "String", "WGAME_CPM_BUSIAPPID", "\"${WGAME_CPM_BUSIAPPID}\""
buildConfigField "String", "WGAME_CPM_API_HOST", "\"${WGAME_CPM_API_HOST}\""
buildConfigField "String", "WECHAT_APPID", "\"${WECHAT_APPID}\""
buildConfigField "String", "WECHAT_SECRET", "\"${WECHAT_SECRET}\""
buildConfigField "String", "TENCENT_APPID", "\"${TENCENT_APPID}\""
buildConfigField "String", "WEIBO_APPKEY", "\"${WEIBO_APPKEY}\""
// 一体包的32位畅玩游戏助手包名
buildConfigField "String", "EXT_PACKAGE_NAME", "\"${rootProject.ext.EXT_PACKAGE_NAME}\""
}
// gradle 2.2以上默认同时启用v1和v2优先用于Android N
@ -129,23 +124,6 @@ android {
}
}
packagingOptions {
// exclude 部分冗余的文件
exclude 'META-INF/gradle/incremental.annotation.processors'
exclude 'darwin/x86_64/liblz4-java.dylib'
exclude 'assets/libwbsafeedit_x86'
exclude 'assets/libwbsafeedit_x86_64'
exclude 'lib/armeabi-v7a/libRSSupport.so'
exclude 'lib/arm64-v8a/libRSSupport.so'
exclude 'lib/armeabi-v7a/librsjni.so'
exclude 'lib/arm64-v8a/librsjni.so'
resources.excludes += "com/j256/*"
resources.excludes += "org/apache/commons/codec/language/bm/*"
}
buildTypes {
debug {
debuggable true
@ -184,15 +162,6 @@ android {
flavorDimensions("env", "region")
sourceSets {
debug {
assets.srcDirs += 'src/main/assets-debug'
}
release {
assets.srcDirs += 'src/main/assets-release'
}
publish {
java.srcDirs = ['src/main/java', "src/default/java"]
}
@ -232,9 +201,6 @@ android {
buildConfigField "String", "QUICK_LOGIN_APPKEY", "\"${DEV_QUICK_LOGIN_APPKEY}\""
buildConfigField "String", "DEV_CSJ_APPID", "\"${DEV_CSJ_APPID}\""
buildConfigField "String", "CSJ_APPID", "\"${CSJ_APPID}\""
buildConfigField "String", "VA_VERSION_NAME", "\"${rootProject.ext.VA_VERSION}-debug\""
manifestPlaceholders.put("VA_VERSION_NAME", "${rootProject.ext.VA_VERSION}-debug")
}
// publish 发布时候使用的 flavor接口仅包含正式环境
@ -248,9 +214,6 @@ android {
buildConfigField "String", "QUICK_LOGIN_APPKEY", "\"${QUICK_LOGIN_APPKEY}\""
buildConfigField "String", "DEV_CSJ_APPID", "\"${CSJ_APPID}\""
buildConfigField "String", "CSJ_APPID", "\"${CSJ_APPID}\""
buildConfigField "String", "VA_VERSION_NAME", "\"${rootProject.ext.VA_VERSION}\""
manifestPlaceholders.put("VA_VERSION_NAME", "${rootProject.ext.VA_VERSION}")
}
tea {
@ -264,10 +227,7 @@ android {
buildConfigField "String", "DEV_CSJ_APPID", "\"${CSJ_APPID}\""
buildConfigField "String", "CSJ_APPID", "\"${CSJ_APPID}\""
buildConfigField "String", "VA_VERSION_NAME", "\"${rootProject.ext.VA_VERSION}\""
manifestPlaceholders.put("APPLOG_SCHEME", "rangersapplog.byAx6uYt".toLowerCase())
manifestPlaceholders.put("VA_VERSION_NAME", "${rootProject.ext.VA_VERSION}")
}
kuaishou {
@ -280,9 +240,6 @@ android {
buildConfigField "String", "QUICK_LOGIN_APPKEY", "\"${QUICK_LOGIN_APPKEY}\""
buildConfigField "String", "DEV_CSJ_APPID", "\"${CSJ_APPID}\""
buildConfigField "String", "CSJ_APPID", "\"${CSJ_APPID}\""
buildConfigField "String", "VA_VERSION_NAME", "\"${rootProject.ext.VA_VERSION}\""
manifestPlaceholders.put("VA_VERSION_NAME", "${rootProject.ext.VA_VERSION}")
}
gdt {
@ -295,9 +252,6 @@ android {
buildConfigField "String", "QUICK_LOGIN_APPKEY", "\"${QUICK_LOGIN_APPKEY}\""
buildConfigField "String", "DEV_CSJ_APPID", "\"${CSJ_APPID}\""
buildConfigField "String", "CSJ_APPID", "\"${CSJ_APPID}\""
buildConfigField "String", "VA_VERSION_NAME", "\"${rootProject.ext.VA_VERSION}\""
manifestPlaceholders.put("VA_VERSION_NAME", "${rootProject.ext.VA_VERSION}")
}
sm {
@ -310,9 +264,6 @@ android {
buildConfigField "String", "QUICK_LOGIN_APPKEY", "\"${QUICK_LOGIN_APPKEY}\""
buildConfigField "String", "DEV_CSJ_APPID", "\"${CSJ_APPID}\""
buildConfigField "String", "CSJ_APPID", "\"${CSJ_APPID}\""
buildConfigField "String", "VA_VERSION_NAME", "\"${rootProject.ext.VA_VERSION}\""
manifestPlaceholders.put("VA_VERSION_NAME", "${rootProject.ext.VA_VERSION}")
}
// 港澳台
@ -342,21 +293,6 @@ repositories {
}
}
// 删除不需要的 assets
android.applicationVariants.configureEach { variant ->
variant.mergeAssets.doLast {
def assetDir = variant.mergeAssetsProvider.get().outputDir.get()
def unwantedAssets = ['2011394667', 'gdt_plugin/gdtadv2.jar']
unwantedAssets.each { assetPath ->
def file = new File([assetDir, assetPath].join(File.separator))
if (file.exists()) {
file.delete()
}
}
}
}
dependencies {
implementation fileTree(include: ['*.jar', '*.aar'], dir: 'libs')
@ -365,12 +301,14 @@ dependencies {
kuaishouImplementation fileTree(include: ['*.jar', '*.aar'], dir: 'src/kuaishou/libs')
gdtImplementation fileTree(include: ['*.jar', '*.aar'], dir: 'src/gdt/libs')
smImplementation fileTree(include: ['*.jar', '*.aar'], dir: 'src/sm/libs')
testImplementation 'junit:junit:4.12'
debugImplementation "com.squareup.leakcanary:leakcanary-android:${leakcanary}"
debugImplementation "com.squareup.leakcanary:leakcanary-android-process:${leakcanary}"
// debugImplementation "com.gu.android:toolargetool:${toolargetool}" // 需要使用调试时才启用
debugImplementation "com.github.nichbar:WhatTheStack:${whatTheStack}"
// debugImplementation "io.github.didi.dokit:dokitx:${dokit}"
implementation "androidx.multidex:multidex:${multiDex}"
implementation "androidx.fragment:fragment-ktx:${fragment}"
@ -380,8 +318,9 @@ dependencies {
implementation "androidx.viewpager2:viewpager2:${viewpager2}"
kapt "androidx.room:room-compiler:${room}"
implementation "com.tencent.vasdolly:helper:${apkChannelPackage}"
implementation "com.tencent.vasdolly:writer:${apkChannelPackage}"
implementation "com.kyleduo.switchbutton:library:${switchButton}"
implementation "com.leon.channel:helper:${apkChannelPackage}"
implementation "com.j256.ormlite:ormlite-android:${ormlite}"
implementation "com.j256.ormlite:ormlite-core:${ormlite}"
@ -402,14 +341,14 @@ dependencies {
exclude module: "gsyvideoplayer-androidvideocache"
exclude group: "tv.danmaku.ijk.media"
})
implementation ("com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-exo_player2:$gsyVideo") {
exclude group: 'com.google.android.exoplayer', module: 'extension-rtmp'
}
implementation "com.github.CarGuo.GSYVideoPlayer:gsyVideoPlayer-exo_player2:$gsyVideo"
// implementation "androidx.work:work-runtime:${workManager}"
implementation "com.llew.huawei:verifier:${verifier}"
teaImplementation "com.bytedance.applog:RangersAppLog-Lite-cn:${bytedanceApplog}"
teaImplementation "com.bytedance.ads:AppConvert:${bytedanceAppConvert}"
teaImplementation "com.bytedance.applog:RangersAppLog-All-convert:${bytedanceApplog}"
implementation "net.lingala.zip4j:zip4j:${zip4j}"
@ -418,109 +357,57 @@ dependencies {
implementation "com.lg:easyfloat:${easyFloat}"
implementation("com.lg:apksig:${apksig}") {
exclude group: 'com.google.protobuf'
}
implementation "io.github.florent37:shapeofview:${shapeOfView}"
implementation "com.lg:apksig:${apksig}"
implementation "com.lg:gid:${gid}"
implementation "com.lg:shortcut:${shortcut}"
coreLibraryDesugaring "com.android.tools:desugar_jdk_libs:${desugarJdkLibs}"
kapt "com.alibaba:arouter-compiler:$arouterVersion"
implementation project(':ndownload')
implementation project(':vspace-bridge:vspace')
implementation(project(':feature:xapk-installer'))
implementation(project(':module_common')) {
implementation (project(':module_common')) {
exclude group: 'androidx.swiperefreshlayout'
}
implementation(project(':module_login')) {
exclude group: 'androidx.swiperefreshlayout'
}
implementation(project(':module_core_feature')) {
exclude group: 'androidx.swiperefreshlayout'
}
implementation(project(':module_setting')) {
exclude group: 'androidx.swiperefreshlayout'
}
// implementation(project(':module_setting_compose')) {
// exclude group: 'androidx.swiperefreshlayout'
// }
if (!gradle.ext.excludeOptionalModules || gradle.ext.enablePkg) {
implementation(project(':feature:pkg'))
// implementation(project(':module_setting_compose')) {
// exclude group: 'androidx.swiperefreshlayout'
// }
implementation(project(':module_core_feature')) {
exclude group: 'androidx.swiperefreshlayout'
}
if (!gradle.ext.excludeOptionalModules || gradle.ext.enableFeedback) {
implementation(project(':feature:new_feedback')) {
exclude group: 'androidx.swiperefreshlayout'
}
// implementation(project(':module_feedback')) {
// exclude group: 'androidx.swiperefreshlayout'
// }
implementation(project(':feature:new_feedback',)) {
exclude group: 'androidx.swiperefreshlayout'
}
if (!gradle.ext.excludeOptionalModules || gradle.ext.enableMessage) {
implementation(project(':module_message')) {
exclude group: 'androidx.swiperefreshlayout'
}
implementation(project(':module_sensors_data')) {
exclude group: 'androidx.swiperefreshlayout'
}
if (!gradle.ext.excludeOptionalModules || gradle.ext.enableOaid) {
implementation(project(':feature:oaid'))
implementation(project(':module_message')) {
exclude group: 'androidx.swiperefreshlayout'
}
if (!gradle.ext.excludeOptionalModules || gradle.ext.enableFloatingWindow) {
implementation(project(':feature:floating-window'))
// implementation(project(':feature:vpn'))
implementation(project(':feature:pkg'))
implementation(project(':feature:oaid'))
implementation(project(':feature:floating-window'))
implementation(project(':feature:csj_ad'))
// implementation(project(':feature:beizi_startup_ad'))
implementation(project(':feature:xapk-installer'))
implementation(project(':feature:qq_game')) {
exclude group: 'androidx.swiperefreshlayout'
}
if (!gradle.ext.excludeOptionalModules || gradle.ext.enableSensorData) {
implementation(project(':module_sensors_data')) {
exclude group: 'androidx.swiperefreshlayout'
}
}
if (!gradle.ext.excludeOptionalModules || gradle.ext.enableCsjAd) {
implementation(project(':feature:csj_ad'))
}
if (!gradle.ext.excludeOptionalModules || gradle.ext.enableQQGame) {
implementation(project(':feature:qq_game')) {
exclude group: 'androidx.swiperefreshlayout'
}
}
if (!gradle.ext.excludeOptionalModules || gradle.ext.enablePush) {
def pushProperty = findProperty('BUILD_PUSH_TYPE')
// 根据BUILD_PUSH_TYPE决定使用哪个推送SDK目前默认使用极光推送
def pushProject = (pushProperty == null || pushProperty == 'jg')
? project(':feature:jg_push') : project(':feature:acloud_push')
implementation(pushProject) {
exclude group: 'androidx.swiperefreshlayout'
}
}
if (!gradle.ext.excludeOptionalModules || gradle.ext.enableSentry) {
implementation(project(':feature:sentry'))
}
implementation(project(':feature:media_select'))
implementation(project(":module_va_api"))
implementation(project(":va-archive-common"))
if (!gradle.ext.excludeOptionalModules || gradle.ext.enableVa) {
implementation(project(":module_va_impl"))
}
debugImplementation "com.bytedance.tools.codelocator:codelocator-core:2.0.3"
internalImplementation(project(':module_internal_test'))
debugImplementation 'com.bytedance.android:shadowhook:1.0.9'
debugImplementation 'io.github.shiqos:wytrace:1.0.1'
}
File propFile = file('sign.properties')
@ -580,6 +467,106 @@ if (propFile.exists()) {
// }.each { t -> t.dependsOn generateMetaJson }
//}
andResGuard {
mappingFile = null
use7zip = true
useSign = true
// 打开这个开关会keep住所有资源的原始路径只混淆资源的名字
keepRoot = false
// 设置这个值会把arsc name列混淆成相同的名字减少string常量池的大小
fixedResName = "arg"
// 打开这个开关会合并所有哈希值相同的资源,但请不要过度依赖这个功能去除去冗余资源
mergeDuplicatedRes = true
whiteList = [
"R.drawable.icon",
"R.drawable.ic_bar_back",
"R.drawable.toolbar_search_icon",
"R.drawable.bg_notification_answer_style_1",
"R.drawable.bg_notification_answer_style_2",
"R.drawable.bg_notification_article_style_1",
"R.drawable.bg_notification_article_style_2",
"R.drawable.bg_notification_feedback_style_1",
"R.drawable.bg_notification_feedback_style_2",
"R.drawable.bg_notification_gift_style_1",
"R.drawable.bg_notification_gift_style_2",
"R.drawable.bg_notification_login_style_1",
"R.drawable.bg_notification_login_style_2",
"R.drawable.bg_notification_question_style_1",
"R.drawable.bg_notification_question_style_2",
"R.drawable.bg_notification_rating_style_1",
"R.drawable.bg_notification_rating_style_2",
"R.drawable.bg_notification_reserve_game_style_1",
"R.drawable.bg_notification_reserve_game_style_2",
"R.drawable.bg_notification_video_style_1",
"R.drawable.bg_notification_video_style_2",
"R.drawable.ic_recommend_activity",
"R.drawable.ic_recommend_discount",
"R.drawable.ic_recommend_function",
"R.drawable.ic_recommend_gift",
"R.drawable.ic_recommend_role",
"R.drawable.download_button_normal_style",
"R.drawable.ic_selector_selected",
"R.drawable.ic_selector_default",
"R.id.download_speed",
"R.id.download_percentage",
"R.id.comment",
"R.id.vote",
"R.id.watermark_hint",
"R.id.watermark_sb",
"R.id.bottomShareIv",
"R.id.bottomShareTv",
"R.id.recommendStarPref",
"R.id.recommendStar",
"R.id.iv_vmode_badge",
"R.id.tv_vmode",
"R.id.iv_vmode",
"R.drawable.help_search_delete",
"R.drawable.suggest_type_normal",
"R.drawable.suggest_type_crash",
"R.drawable.suggest_type_game_question",
"R.drawable.suggest_type_game_collect",
"R.drawable.suggest_type_function_suggest",
"R.drawable.suggest_type_article_collect",
"R.drawable.suggest_type_copyright",
"R.drawable.news_comment_detail_read",
"R.drawable.news_comment_detail_comment",
"R.drawable.news_comment_detail_share",
"R.drawable.ic_libao",
"R.drawable.ic_link",
"R.drawable.concern_message_icon",
"R.drawable.reuse_blank_hint",
"R.drawable.ic_concern",
"R.drawable.concern_down",
"R.drawable.concern_up",
"R.drawable.ic_libao_more",
"R.drawable.ic_libao_delete",
"R.drawable.ic_dialog_close",
"R.drawable.occupy2",
"R.drawable.kc_checkbox_unselect",
"R.drawable.kc_checkbox_select",
"R.drawable.ic_type_unselect",
"R.drawable.ic_type_selected",
"R.drawable.suggest_add_pic_icon",
"R.drawable.icon_pic_add",
"R.drawable.ask_search_input_delete",
"R.drawable.suggest_pic_delete",
"R.id.cardIv",
"R.id.cardMask",
"R.id.cardGradientMask",
"R.id.gameIconIv",
"R.id.titleContainer"
]
compressFilePattern = [
"*.png",
"*.jpg",
"*.jpeg",
"*.gif",
]
sevenzip {
artifact = 'io.github.leon406:SevenZip:1.2.22.5'
}
}
project.afterEvaluate {
def variants = null
try {

View File

@ -80,6 +80,9 @@
### EasyFloat
-keep class com.lzf.easyfloat.* {*;}
### dokit
-keep class com.didichuxing.** {*;}
### 广点通SDK
-dontwarn com.qq.gdt.action.**
-keep class com.qq.gdt.action.** {*;}

View File

@ -8,7 +8,7 @@ import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.utils.PackageFlavorHelper
import com.gh.gamecenter.core.provider.IFlavorProvider
import com.gh.gamecenter.core.utils.SPUtils
import com.tencent.vasdolly.helper.ChannelReaderUtil
import com.leon.channel.helper.ChannelReaderUtil
class FlavorProviderImp : IFlavorProvider {
override fun getChannelStr(application: Application): String {

View File

@ -28,9 +28,6 @@ object GdtHelper {
} else {
GDTAction.init(application, USER_ACTION_SET_ID, APP_SECRET_ID, channel)
}
GDTAction.start()
Utils.log("init GdtHelper")
}

View File

@ -8,7 +8,7 @@ import com.gh.gamecenter.core.provider.IFlavorProvider
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.core.utils.TimeUtils
import com.halo.assistant.HaloApp
import com.tencent.vasdolly.helper.ChannelReaderUtil
import com.leon.channel.helper.ChannelReaderUtil
class FlavorProviderImp : IFlavorProvider {

Binary file not shown.

View File

@ -6,37 +6,27 @@ import android.view.View
import android.view.ViewGroup
import androidx.annotation.Keep
import com.gh.gamecenter.R
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.databinding.LayoutPersonalOtherItemBinding
import com.gh.vspace.installexternalgames.InstallExternalGameActivity
import com.lightgame.utils.Utils
import java.io.File
@Keep
class ExternalGameUsage : ITestCase {
private fun buttonTemplate(viewParent: ViewGroup, id: Int, fn: (LayoutPersonalOtherItemBinding) -> Unit) {
class ExternalGameUsage : IExternalGamesUsage {
override fun addInstallExternalGameButton(viewParent: ViewGroup) {
val context = viewParent.context
viewParent.findViewById<View>(id) ?: run {
viewParent.findViewById<View>(R.id.install_game_from_external) ?: run {
val binding = LayoutPersonalOtherItemBinding.inflate(LayoutInflater.from(context)).apply {
root.id = id
fn(this)
root.id = R.id.install_game_from_external
titleTv.text = context.getString(R.string.title_install_external_game)
iconIv.setImageResource(R.drawable.ic_personal_my_game)
root.setOnClickListener {
VHelper.connectService {
context.startActivity(
InstallExternalGameActivity.getIntent(context)
.apply { flags = flags or Intent.FLAG_ACTIVITY_NEW_TASK })
}
}
}
viewParent.addView(binding.root, 0)
}
}
override fun addInstallExternalGameButton(viewParent: ViewGroup) {
val context = viewParent.context
buttonTemplate(viewParent, R.id.install_game_from_external) {
it.titleTv.text = context.getString(R.string.title_install_external_game)
it.iconIv.setImageResource(R.drawable.ic_personal_my_game)
it.root.setOnClickListener {
context.startActivity(
InstallExternalGameActivity.getIntent(context)
.apply { flags = flags or Intent.FLAG_ACTIVITY_NEW_TASK })
}
}
}
}

View File

@ -25,11 +25,6 @@ class ExternalGameAdapter(private val games: List<ExternalGameUiState>, private
路径:${item.apkPath}
""".trimIndent()
}
holder.update.setOnClickListener {
onItemClickListener.onItemClick(item, OnItemClickListener.ClickType.CLICK_INSTALL)
}
holder.install.goneIf(item.isInstalled) {
holder.install.setOnClickListener {
onItemClickListener.onItemClick(item, OnItemClickListener.ClickType.CLICK_INSTALL)

View File

@ -8,5 +8,4 @@ class ExternalGameViewHolder(binding: LayoutExternalGameItemBinding) : RecyclerV
val install = binding.btnInstall
val uninstall = binding.btnUninstall
val start = binding.btnStart
val update = binding.btnUpdate
}

View File

@ -1,14 +1,10 @@
package com.gh.vspace.installexternalgames
import android.Manifest
import android.app.Dialog
import android.content.ComponentName
import android.content.pm.PackageManager
import android.os.Bundle
import androidx.activity.result.contract.ActivityResultContracts
import androidx.core.content.ContextCompat
import androidx.recyclerview.widget.LinearLayoutManager
import com.gh.common.util.DialogUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.fragment.ToolbarFragment
import com.gh.gamecenter.common.exposure.meta.MetaUtil
import com.gh.gamecenter.common.utils.dip2px
@ -20,7 +16,6 @@ import com.gh.gamecenter.databinding.FragmentInstallExternalGamesBinding
import com.gh.vspace.VHelper
import com.halo.assistant.HaloApp
import com.lg.vspace.VirtualAppManager
import com.lightgame.download.DownloadEntity
import io.reactivex.Single
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
@ -44,19 +39,6 @@ class InstallExternalGameFragment : ToolbarFragment(), OnItemClickListener {
private lateinit var dialog: Dialog
private val requestPermissionLauncher = registerForActivityResult<String, Boolean>(
ActivityResultContracts.RequestPermission()
) { result ->
if (result == true) {
// grant
mViewModel.scanPaths()
} else {
// not grant
}
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setNavigationTitle(getString(com.gh.gamecenter.R.string.title_install_external_game))
@ -73,30 +55,11 @@ class InstallExternalGameFragment : ToolbarFragment(), OnItemClickListener {
)
adapter.notifyDataSetChanged()
}
mViewModel.scanPaths()
requestStoragePermission()
}
private fun requestStoragePermission() {
when {
ContextCompat.checkSelfPermission(
requireContext(),
Manifest.permission.READ_EXTERNAL_STORAGE
) == PackageManager.PERMISSION_GRANTED -> {
mViewModel.scanPaths()
}
shouldShowRequestPermissionRationale(Manifest.permission.READ_EXTERNAL_STORAGE) -> {
requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE)
}
else -> {
requestPermissionLauncher.launch(Manifest.permission.READ_EXTERNAL_STORAGE)
}
}
}
private fun initView() {
dialog = DialogUtils.showWaitDialog(requireContext(), "")
mBinding.externalGamesList.let {
@ -104,7 +67,7 @@ class InstallExternalGameFragment : ToolbarFragment(), OnItemClickListener {
it.layoutManager = LinearLayoutManager(requireContext())
val itemDecoration = HorizontalDividerItemDecoration.Builder(requireContext())
.size(2F.dip2px())
.color(com.gh.gamecenter.common.R.color.ui_divider.toColor(requireContext()))
.color(R.color.ui_divider.toColor(requireContext()))
.build()
if (it.itemDecorationCount != 0) {
it.removeItemDecorationAt(0)
@ -130,11 +93,9 @@ class InstallExternalGameFragment : ToolbarFragment(), OnItemClickListener {
OnItemClickListener.ClickType.CLICK_INSTALL -> {
install(externalGameUiState)
}
OnItemClickListener.ClickType.CLICK_UNINSTALL -> {
uninstall(externalGameUiState)
}
OnItemClickListener.ClickType.CLICK_START -> {
start(externalGameUiState)
}
@ -142,21 +103,21 @@ class InstallExternalGameFragment : ToolbarFragment(), OnItemClickListener {
}
private fun install(externalGameUiState: ExternalGameUiState) {
VHelper.disableLaunchGameAfterInstallation()
VHelper.install(requireContext(), DownloadEntity().apply {
externalGameUiState.externalGameEntity.apply {
packageName = apkPackageName
path = apkPath
}
}, true)
VHelper.newCwValidateVspaceBeforeAction(
requireContext(),null,
) {
dialog.show()
val bit =
externalGameUiState.externalGameEntity.cpuAbi.let { if (it.size == 1 && it.contains("armeabi-v7a")) "32" else "64" }
if (VHelper.showDialogIfVSpaceIsNeeded(
requireContext(),
"",
externalGameUiState.externalGameEntity.appName,
"",
bit = bit
)
) return
dialog.show()
externalGameUiState.externalGameEntity.let {
val intent = VirtualAppManager.getInstallIntent(context, it.apkPath, it.apkPackageName)
requireActivity().startActivity(intent)
}
}
private fun uninstall(externalGameUiState: ExternalGameUiState) {
@ -183,15 +144,7 @@ class InstallExternalGameFragment : ToolbarFragment(), OnItemClickListener {
com.gh.gamecenter.BuildConfig.VERSION_NAME,
HaloApp.getInstance().channel,
"",
"",
com.gh.gamecenter.BuildConfig.VA_VERSION_NAME,
HaloApp.getInstance().oaid
)
intent.setComponent(
ComponentName(
com.gh.gamecenter.BuildConfig.APPLICATION_ID,
VirtualAppManager.AIDL_SERVER_REMOTE_GUIDE_ACTIVITY
)
""
)
requireActivity().startActivity(intent)
}

View File

@ -24,14 +24,6 @@
android:visibility="gone"
tools:visibility="visible" />
<Button
android:id="@+id/btn_update"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/text_update"
android:visibility="visible"
tools:visibility="visible" />
<Button
android:id="@+id/btn_uninstall"
android:layout_width="wrap_content"

View File

@ -2,7 +2,6 @@
<resources>
<string name="title_install_external_game">從SD卡安裝</string>
<string name="text_install">安裝</string>
<string name="text_update">更新</string>
<string name="text_uninstall">卸載</string>
<string name="text_start">啟動</string>
</resources>

View File

@ -2,7 +2,6 @@
<resources>
<string name="title_install_external_game">从SD卡安装</string>
<string name="text_install">安装</string>
<string name="text_update">更新</string>
<string name="text_uninstall">卸载</string>
<string name="text_start">启动</string>
</resources>

View File

@ -12,7 +12,7 @@ import com.gh.gamecenter.core.utils.TimeUtils
import com.gh.gamecenter.core.utils.ToastUtils
import com.halo.assistant.HaloApp
import com.kwai.monitor.payload.TurboHelper
import com.tencent.vasdolly.helper.ChannelReaderUtil
import com.leon.channel.helper.ChannelReaderUtil
class FlavorProviderImp : IFlavorProvider {

Binary file not shown.

View File

@ -7,29 +7,10 @@
<package android:name="com.gh.gamecenter" />
</queries>
<queries>
<package android:name="com.gh.toolmap" />
<intent>
<action android:name="android.intent.action.VIEW"/>
<category android:name="android.intent.category.BROWSABLE"/>
<data android:scheme="ghtoolmap"/>
</intent>
</queries>
<queries>
<package android:name="com.lg.vspace" />
<package android:name="com.gh.gamecenter.addon" />
</queries>
<!-- 华为/荣耀角标 -->
<uses-permission android:name="com.huawei.android.launcher.permission.CHANGE_BADGE " />
<uses-permission android:name="com.hihonor.android.launcher.permission.CHANGE_BADGE" />
<!-- vivo角标 -->
<uses-permission android:name="com.vivo.notification.permission.BADGE_ICON" />
<uses-permission
android:name="android.permission.MANAGE_EXTERNAL_STORAGE"
tools:ignore="ScopedStorage" />
<!-- 允许应用程序访问网络连接 -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- 允许应用程序写入外部存储如SD卡上写文件 -->
@ -50,7 +31,7 @@
<uses-permission android:name="com.android.launcher.permission.INSTALL_SHORTCUT" />
<!-- 应用安装相关 -->
<uses-permission android:name="com.android.permission.GET_INSTALLED_APPS" />
<uses-permission android:name="android.permission.QUERY_ALL_PACKAGES" />
<!-- 前台服务权限-->
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
@ -65,9 +46,6 @@
<!-- 如果有视频相关的广告且使用textureView播放请务必添加否则黑屏 -->
<uses-permission android:name="android.permission.WAKE_LOCK" />
<!-- 悬浮窗 -->
<uses-permission android:name="android.permission.SYSTEM_ALERT_WINDOW" />
<uses-sdk tools:overrideLibrary="
com.shuyu.gsyvideoplayer,
com.shuyu.gsyvideoplayer.lib,
@ -106,33 +84,7 @@
com.tencent.qqmini,
com.tencent.qqmini.minigame.external,
com.tencent.qqmini.minigame.opensdk,
com.tencent.qqmini.union.ad,
com.lg.vspace,
io.lg.va.common,
com.va.floating,
com.lg.cloud,
com.lg.archive,
com.lg.vclient,
com.va.realname,
com.lg.vspace.flavor,
com.lg.update,
com.lg.login,
com.lg.accelerator,
com.lody.virtual,
com.lg.core,
com.lg.ads,
com.lg.common,
com.lg.vspace.network,
com.lody.virtual.lib.res,
com.va.host,
com.lg.vspace.plugin.host,
com.lg.plugin.constant,
com.bytedance.tools.codelocator,
org.chickenhook.restrictionbypass,
com.lody.virtual.sandhook,
com.lg.vspace.common,
com.lg.vspace.archive.common,
com.wy.lib.wytrace" />
com.tencent.qqmini.union.ad" />
<!-- 去掉 SDK 一些流氓权限 -->
<uses-permission
@ -151,14 +103,6 @@
android:name="android.permission.ACCESS_COARSE_LOCATION"
tools:node="remove" />
<uses-permission
android:name="android.permission.ACCESS_BACKGROUND_LOCATION"
tools:node="remove" />
<uses-permission
android:name="android.permission.ACCESS_FINE_LOCATION"
tools:node="remove" />
<supports-screens
android:anyDensity="true"
android:largeScreens="true"
@ -174,12 +118,10 @@
android:label="@string/app_name"
android:largeHeap="true"
android:networkSecurityConfig="@xml/network_security_config"
android:preserveLegacyExternalStorage="true"
android:requestLegacyExternalStorage="true"
android:resizeableActivity="true"
android:theme="@style/AppCompatTheme.APP"
tools:replace="android:name,android:allowBackup"
tools:targetApi="r">
tools:targetApi="n">
<meta-data
android:name="EasyGoClient"
@ -194,8 +136,6 @@
android:name="io.sentry.breadcrumbs.system-events"
android:value="false" />
<meta-data android:name="module_version" android:value="${VA_VERSION_NAME}" />
<service android:name="com.gh.ndownload.NDownloadService" />
<activity
@ -320,6 +260,10 @@
android:name="com.gh.gamecenter.CleanApkActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.SelectUserIconActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.CommentDetailActivity"
android:screenOrientation="portrait"
@ -344,6 +288,14 @@
android:screenOrientation="portrait"
android:windowSoftInputMode="stateHidden" />
<activity
android:name=".category.CategoryDirectoryActivity"
android:screenOrientation="portrait" />
<activity
android:name=".category.CategoryListActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.UserInfoActivity"
android:screenOrientation="portrait" />
@ -361,6 +313,14 @@
android:screenOrientation="portrait"
android:windowSoftInputMode="stateHidden" />
<activity
android:name="com.gh.gamecenter.qa.answer.detail.AnswerDetailActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.qa.answer.edit.AnswerEditActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.InfoActivity"
android:screenOrientation="portrait" />
@ -369,6 +329,10 @@
android:name=".qa.questions.invite.QuestionsInviteActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.qa.myqa.MyAskActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.qa.questions.edit.QuestionEditActivity"
android:screenOrientation="portrait" />
@ -406,6 +370,10 @@
android:name="com.gh.gamecenter.qa.article.edit.ArticleEditActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.qa.article.MyArticleActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.qa.article.draft.ArticleDraftActivity"
android:screenOrientation="portrait" />
@ -444,6 +412,10 @@
android:name="com.gh.gamecenter.history.HistoryActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.personalhome.rating.RatingActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.gamedetail.rating.logs.CommentLogsActivity"
android:screenOrientation="portrait" />
@ -465,6 +437,9 @@
android:name="com.gh.gamecenter.video.game.GameVideoActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.qa.editor.LocalMediaActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.servers.GameServersActivity"
@ -497,6 +472,9 @@
android:configChanges="orientation|screenSize|keyboardHidden"
android:screenOrientation="portrait"
android:theme="@style/TransparentStatusBarAndNavigationBar" />
<activity
android:name=".gamedetail.myrating.MyRatingActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.gamedetail.fuli.kaifu.ServersCalendarActivity"
@ -510,6 +488,9 @@
android:name=".gamedetail.fuli.kaifu.ServersSubscribedGameListActivity"
android:screenOrientation="portrait" />
<activity
android:name=".qa.answer.draft.AnswerDraftActivity"
android:screenOrientation="portrait" />
<activity
android:name=".gamedetail.rating.RatingFoldActivity"
android:screenOrientation="portrait" />
@ -521,6 +502,10 @@
android:name=".video.poster.PosterEditActivity"
android:screenOrientation="portrait" />
<activity
android:name=".video.poster.PosterClipActivity"
android:screenOrientation="portrait" />
<activity
android:name=".forum.detail.ForumDetailActivity"
android:screenOrientation="portrait" />
@ -562,6 +547,14 @@
android:name=".simulatorgame.SimulatorManagementActivity"
android:screenOrientation="portrait" />
<activity
android:name=".catalog.CatalogActivity"
android:screenOrientation="portrait" />
<activity
android:name=".catalog.NewCatalogListActivity"
android:screenOrientation="portrait" />
<activity
android:name=".forum.search.ForumOrUserSearchActivity"
android:screenOrientation="portrait" />
@ -582,6 +575,10 @@
android:name=".personal.DeliveryInfoActivity"
android:screenOrientation="portrait" />
<activity
android:name=".qa.editor.PreviewVideoActivity"
android:screenOrientation="portrait" />
<activity
android:name=".qa.video.publish.VideoPublishActivity"
android:screenOrientation="portrait" />
@ -767,11 +764,11 @@
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.minigame.qq.QGameHomeWrapperActivity"
android:name="com.gh.gamecenter.qgame.QGameHomeWrapperActivity"
android:screenOrientation="portrait" />
<activity
android:name="com.gh.gamecenter.minigame.MiniGameSearchActivity"
android:name="com.gh.gamecenter.qgame.QGameSearchActivity"
android:screenOrientation="portrait" />
<activity
@ -790,24 +787,6 @@
android:name="com.gh.gamecenter.wrapper.ToolbarWrapperActivity"
android:screenOrientation="portrait" />
<activity
android:name=".forum.home.CommunityActivity"
android:screenOrientation="portrait" />
<activity
android:name=".forum.home.follow.FollowDynamicActivity"
android:theme="@style/Theme.Transparent" />
<activity
android:name=".forum.home.follow.AllFollowedActivity"
android:screenOrientation="portrait"
android:theme="@style/AppCompatTheme.APP" />
<activity
android:name=".search.SearchTabActivity"
android:configChanges="keyboardHidden"
android:screenOrientation="portrait"
android:theme="@style/AppCompatTheme.APP" />
<!-- <activity-->
<!-- android:name="${applicationId}.douyinapi.DouYinEntryActivity"-->
@ -819,8 +798,7 @@
android:name="androidx.core.content.FileProvider"
android:authorities="${applicationId}"
android:exported="false"
android:grantUriPermissions="true"
tools:replace="android:authorities">
android:grantUriPermissions="true">
<meta-data
android:name="android.support.FILE_PROVIDER_PATHS"
android:resource="@xml/provider_paths" />
@ -866,8 +844,6 @@
<service android:name="com.gh.gamecenter.install.InstallService" />
<service android:name="com.gh.download.suspendwindow.DownloadSuspendWindowService" />
<receiver
android:name="com.gh.gamecenter.receiver.DownloadReceiver"
android:exported="false">
@ -895,6 +871,7 @@
<action android:name="com.gh.gamecenter.ACTIVITYSKIP" />
</intent-filter>
</receiver>
</application>
</manifest>

View File

@ -6,6 +6,8 @@
<link rel="stylesheet" type="text/css" href="normalize.css">
<link rel="stylesheet" type="text/css" href="style.css">
<link rel="stylesheet" type="text/css" href="video-js.min.css">
<!-- <link rel="stylesheet" href="https://static-web.ghzs.com/website-static/lib/video-js.min.css">--> <!--在web页面播放视频-->
<!--<link rel="stylesheet" type="text/css" href="https://resource.ghzs.com/css/halo_app.css">-->
</head>
<body style="overflow-x: hidden; word-break: break-all;">
@ -13,5 +15,8 @@
<script type="text/javascript" src="zepto.min.js"></script>
<script type="text/javascript" src="rich_editor.js"></script>
<script type="text/javascript" src="video.min.js"></script>
<!--<script src="https://static-web.ghzs.com/website-static/lib/video.min.js"></script>--> <!--在web页面播放视频-->
<!--<script type="text/javascript" src="content.js"></script>-->
<!--<script type="text/javascript" src="https://resource.ghzs.com/js/halo_app.js"></script>-->
</body>
</html>

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
{"v":"5.6.9","fr":30,"ip":0,"op":20,"w":66,"h":66,"nm":"bottom bar tab/论坛/选中/E","ddd":0,"assets":[{"id":"comp_0","layers":[{"ddd":0,"ind":1,"ty":4,"nm":"白-修正","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[33,33,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":0,"s":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":4,"s":[80,80,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.333,0.333,0.333],"y":[0,0,0]},"t":9,"s":[110,110,100]},{"t":13,"s":[100,100,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":1,"k":[{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":0,"s":[{"i":[[0,-0.66],[0,0],[1.38,0],[0,1.38],[0,0],[-0.66,0],[0,0]],"o":[[0,0],[0,1.38],[-1.38,0],[0,0],[0,-0.66],[0,0],[0.66,0]],"v":[[2.5,-1.3],[2.5,0],[0,2.5],[-2.5,0],[-2.5,-1.3],[-1.3,-2.5],[1.3,-2.5]],"c":true}]},{"i":{"x":0,"y":1},"o":{"x":0.333,"y":0},"t":4,"s":[{"i":[[0,-0.66],[0,0],[1.38,0],[0,1.38],[0,0],[-0.66,0],[0,0]],"o":[[0,0],[0,1.38],[-1.38,0],[0,0],[0,-0.66],[0,0],[0.66,0]],"v":[[2.5,-0.102],[2.5,0],[0,2.109],[-2.5,0],[-2.5,-0.102],[-1.3,-1.302],[1.3,-1.302]],"c":true}]},{"i":{"x":0.667,"y":1},"o":{"x":1,"y":0},"t":9,"s":[{"i":[[0,-0.66],[0,0],[1.38,0],[0,1.38],[0,0],[-0.66,0],[0,0]],"o":[[0,0],[0,1.38],[-1.38,0],[0,0],[0,-0.66],[0,0],[0.66,0]],"v":[[2.498,-1.845],[2.5,0],[0,2.734],[-2.5,0],[-2.502,-1.845],[-1.302,-3.045],[1.298,-3.045]],"c":true}]},{"t":13,"s":[{"i":[[0,-0.66],[0,0],[1.38,0],[0,1.38],[0,0],[-0.66,0],[0,0]],"o":[[0,0],[0,1.38],[-1.38,0],[0,0],[0,-0.66],[0,0],[0.66,0]],"v":[[2.5,-1.3],[2.5,0],[0,2.5],[-2.5,0],[-2.5,-1.3],[-1.3,-2.5],[1.3,-2.5]],"c":true}]}],"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"fl","c":{"a":0,"k":[1,1,1,1],"ix":4},"o":{"a":0,"k":100,"ix":5},"r":1,"bm":0,"nm":"填充 1","mn":"ADBE Vector Graphic - Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[300,300],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"矩形","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":150,"st":0,"bm":0},{"ddd":0,"ind":3,"ty":4,"nm":"蓝","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[33,33.76,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[100,100,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[-1.8,0.42],[-3.44,-0.79],[-0.09,-1.71],[0,0],[0,0],[1.98,-0.1],[0,0],[0,0],[0,0],[0.62,0.57],[0,0],[0,0],[0,0],[0,0],[0,0],[0.2,1.89],[0,0],[0,0],[0,0]],"o":[[3.44,-0.79],[1.74,0.41],[0,0],[0,0],[0,2],[0,0],[0,0],[0,0],[-0.69,0.52],[0,0],[0,0],[0,0],[0,0],[0,0],[-1.94,0],[0,0],[0,0],[0,0],[0,-1.8]],"v":[[-6.39,-8.971],[6.39,-8.971],[9.49,-5.471],[9.5,-5.271],[9.5,3.249],[5.95,6.989],[5.75,6.999],[3.25,6.999],[0.3,9.209],[-1.95,9.089],[-2.06,8.969],[-2.17,8.849],[-2.21,8.779],[-3.4,6.999],[-5.75,6.999],[-9.48,3.639],[-9.49,3.449],[-9.5,3.249],[-9.5,-5.271]],"c":true},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"bm":0,"g":{"p":3,"k":{"a":0,"k":[0,0.266,0.638,1,0.5,0.242,0.595,1,1,0.217,0.552,1],"ix":9}},"s":{"a":0,"k":[-9.5,-9.561],"ix":5},"e":{"a":0,"k":[9.5,9.561],"ix":6},"t":1,"nm":"color","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[300,300],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"路径","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":150,"st":0,"bm":0}]}],"layers":[{"ddd":0,"ind":1,"ty":0,"nm":"预合成 1","refId":"comp_0","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[33,33,0],"ix":2},"a":{"a":0,"k":[33,33,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":0,"s":[100,100,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":4,"s":[70,70,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":9,"s":[110,110,100]},{"i":{"x":[0.833,0.833,0.833],"y":[0.833,0.833,0.833]},"o":{"x":[0.167,0.167,0.167],"y":[0.167,0.167,0.167]},"t":13,"s":[90,90,100]},{"t":16,"s":[100,100,100]}],"ix":6}},"ao":0,"w":66,"h":66,"ip":0,"op":20,"st":0,"bm":0}],"markers":[]}

File diff suppressed because one or more lines are too long

View File

@ -0,0 +1 @@
{"v":"5.5.9","fr":30,"ip":0,"op":20,"w":66,"h":66,"nm":"tab_video","ddd":0,"assets":[],"layers":[{"ddd":0,"ind":1,"ty":4,"nm":"形状图层 1","parent":2,"sr":1,"ks":{"o":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.771],"y":[0]},"t":0,"s":[0]},{"t":5,"s":[100]}],"ix":11},"r":{"a":0,"k":90,"ix":10},"p":{"a":0,"k":[-3.742,6.835,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":0,"k":[30.937,31.042,100],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ty":"sr","sy":2,"d":1,"pt":{"a":0,"k":3,"ix":3},"p":{"a":0,"k":[0,0],"ix":4},"r":{"a":0,"k":0,"ix":5},"or":{"a":0,"k":29.286,"ix":7},"os":{"a":0,"k":75,"ix":9},"ix":1,"nm":"多边星形路径 1","mn":"ADBE Vector Shape - Star","hd":false},{"ty":"st","c":{"a":0,"k":[1,1,1,1],"ix":3},"o":{"a":0,"k":100,"ix":4},"w":{"a":0,"k":13,"ix":5},"lc":1,"lj":1,"ml":4,"bm":0,"nm":"描边 1","mn":"ADBE Vector Graphic - Stroke","hd":false},{"ty":"tr","p":{"a":0,"k":[-20.75,-13.25],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[102.743,88.578],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"多边星形 1","np":3,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false},{"ty":"tm","s":{"a":0,"k":0,"ix":1},"e":{"a":1,"k":[{"i":{"x":[0.667],"y":[1]},"o":{"x":[0.657],"y":[0]},"t":0,"s":[0]},{"t":8,"s":[100]}],"ix":2},"o":{"a":0,"k":-115,"ix":3},"m":1,"ix":2,"nm":"修剪路径 1","mn":"ADBE Vector Filter - Trim","hd":false}],"ip":0,"op":60,"st":0,"bm":0},{"ddd":0,"ind":2,"ty":4,"nm":"路径 2","sr":1,"ks":{"o":{"a":0,"k":100,"ix":11},"r":{"a":0,"k":0,"ix":10},"p":{"a":0,"k":[33,33.004,0],"ix":2},"a":{"a":0,"k":[0,0,0],"ix":1},"s":{"a":1,"k":[{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.508,0.508,0.333],"y":[0,0,0]},"t":0,"s":[100,100,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.488,0.488,0.333],"y":[0,0,0]},"t":4,"s":[80,80,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.502,0.502,0.333],"y":[0,0,0]},"t":9,"s":[110,110,100]},{"i":{"x":[0.667,0.667,0.667],"y":[1,1,1]},"o":{"x":[0.534,0.534,0.333],"y":[0,0,0]},"t":13,"s":[95,95,100]},{"t":16,"s":[100,100,100]}],"ix":6}},"ao":0,"shapes":[{"ty":"gr","it":[{"ind":0,"ty":"sh","ix":1,"ks":{"a":0,"k":{"i":[[0,0],[2.16,0.38],[3.22,-0.55],[0.38,-2.16],[-0.55,-3.22],[-2.16,-0.38],[-1.63,0],[-1.61,0.27],[-0.38,2.16],[0.55,3.22]],"o":[[-0.38,-2.16],[-3.22,-0.55],[-2.16,0.38],[-0.55,3.22],[0.38,2.16],[1.61,0.27],[1.63,0],[2.16,-0.38],[0.55,-3.22],[0,0]],"v":[[9.09,-4.86],[4.86,-9.09],[-4.86,-9.09],[-9.09,-4.86],[-9.09,4.86],[-4.86,9.09],[0,9.5],[4.86,9.09],[9.09,4.86],[9.09,-4.86]],"c":true},"ix":2},"nm":"路径 1","mn":"ADBE Vector Shape - Group","hd":false},{"ty":"gf","o":{"a":0,"k":100,"ix":10},"r":1,"bm":0,"g":{"p":3,"k":{"a":0,"k":[0,0.266,0.638,1,0.5,0.242,0.595,1,1,0.217,0.552,1],"ix":9}},"s":{"a":0,"k":[-5.174,-4.43],"ix":5},"e":{"a":0,"k":[8.612,8.214],"ix":6},"t":1,"nm":"Gradient Fill 3","mn":"ADBE Vector Graphic - G-Fill","hd":false},{"ty":"tr","p":{"a":0,"k":[0,0],"ix":2},"a":{"a":0,"k":[0,0],"ix":1},"s":{"a":0,"k":[300,300],"ix":3},"r":{"a":0,"k":0,"ix":6},"o":{"a":0,"k":100,"ix":7},"sk":{"a":0,"k":0,"ix":4},"sa":{"a":0,"k":0,"ix":5},"nm":"变换"}],"nm":"路径","np":2,"cix":2,"bm":0,"ix":1,"mn":"ADBE Vector Group","hd":false}],"ip":0,"op":60,"st":0,"bm":0}],"markers":[]}

View File

@ -34,18 +34,18 @@ try {
var script = document.createElement("script")
document.body.appendChild(script)
if (isDebug) {
script.src = "https://dev-and-static.ghzs66.com/web/js/halo.js" + "?timestamp=" + Math.round(new Date().getTime() / 1000)
script.src = "https://resource.ghzs.com/js/halo_app_test.js" + "?timestamp=" + Math.round(new Date().getTime() / 1000)
} else {
script.src = "https://and-static.ghzs66.com/web/js/halo.js" + "?timestamp=" + Math.round(new Date().getTime() / 1000 / 1000)
script.src = "https://resource.ghzs.com/js/halo.js" + "?timestamp=" + Math.round(new Date().getTime() / 1000 / 1000)
}
var style = document.createElement("link")
style.rel = "stylesheet"
style.type = "text/css"
if (isDebug) {
style.href = "https://dev-and-static.ghzs66.com/web/css/halo.css" + "?timestamp=" + Math.round(new Date().getTime() / 1000)
style.href = "https://resource.ghzs.com/css/halo_app_test.css" + "?timestamp=" + Math.round(new Date().getTime() / 1000)
} else {
style.href = "https://and-static.ghzs66.com/web/css/halo.css" + "?timestamp=" + Math.round(new Date().getTime() / 1000 / 1000)
style.href = "https://resource.ghzs.com/css/halo.css" + "?timestamp=" + Math.round(new Date().getTime() / 1000 / 1000)
}
document.head.appendChild(style)
@ -588,7 +588,7 @@ document.addEventListener("selectionchange", function(e) {
});
document.addEventListener("selectionchange", function(e) {
setTimeout(() => RE.enabledEditingItems(e), 10)
RE.enabledEditingItems(e)
});
RE.recursion = function(dom) {

View File

@ -4,7 +4,6 @@ import android.annotation.SuppressLint
import android.app.Activity
import android.content.Context
import android.content.SharedPreferences
import android.os.Message
import android.text.TextUtils
import android.view.View
import android.view.ViewGroup
@ -28,7 +27,7 @@ import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.common.exposure.ExposureSource
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.AppExecutor
import com.gh.gamecenter.core.provider.IBeiziAdProvider
import com.gh.gamecenter.core.provider.ICsjAdProvider
import com.gh.gamecenter.core.utils.CurrentActivityHolder
import com.gh.gamecenter.core.utils.SPUtils
@ -46,13 +45,16 @@ import io.reactivex.schedulers.Schedulers
*
* 由它来分发功能实现到具体的实现
*
* 以开屏广告为例,有种实现1. 自有的广告实现 2. 穿山甲的开屏广告实现
* 以最复杂的开屏广告为例,有种实现1. 自有的广告实现 2. 穿山甲的开屏广告实现 3. Beizi 的开屏广告实现
*
* 由于两个广告 SDK 有可能在一次启动中都被使用,所以会根据获取到的广告配置 config 来决定是否需要出是很好两个 SDK
*/
object AdDelegateHelper {
private var mCsjAdImpl: ICsjAdProvider? = null
private var mBeiziAdImpl: IBeiziAdProvider? = null
private val mAdConfigList: ArrayList<AdConfig> by lazy { arrayListOf() }
private var mAdConfigList: ArrayList<AdConfig>? = null
private var mSplashAd: AdConfig? = null
private var mDownloadManagerAd: AdConfig? = null
@ -62,10 +64,8 @@ object AdDelegateHelper {
val vGameLaunchAd: AdConfig?
get() = mVGameLaunchAd
val splashAdDisplayInterval: Int
get() = mSplashAd?.ownerAd?.startAd?.displayInterval ?: 3
private const val AD_SDK_CSJ = "穿山甲"
private const val AD_SDK_BEIZI = "倍孜"
const val AD_TYPE_SDK = "third_party_ads" // 第三方 SDK 广告
const val AD_TYPE_OWNER = "owner_ads" // 自有广告
@ -79,19 +79,13 @@ object AdDelegateHelper {
var gameSearchKeyword = ""
fun initAdSdk(context: Context) {
if (AdPluginDownloadHelper.isCsjPluginDownloaded()) {
initAdSdkInternal(context)
} else {
// 首次启动,为了不影响首页加载,延迟 3 秒再下载广告插件并初始化
AppExecutor.uiExecutor.executeWithDelay({
AdPluginDownloadHelper.downloadPluginIfNeeded(isCsj = true) {
initAdSdkInternal(context)
}
}, 3000L)
// 初始化 Beizi
if (mBeiziAdImpl == null) {
mBeiziAdImpl =
ARouter.getInstance().build(RouteConsts.provider.beiziAd).navigation() as? IBeiziAdProvider
mBeiziAdImpl?.initSDK(context)
}
}
private fun initAdSdkInternal(context: Context) {
// 初始化穿山甲
if (mCsjAdImpl == null) {
mCsjAdImpl =
@ -112,7 +106,7 @@ object AdDelegateHelper {
@SuppressLint("CheckResult")
fun requestAdConfig(isFromRetry: Boolean, keyword: String = "", callback: (() -> Unit)? = null) {
// mAdConfigList 不为空不需要重试
if (isFromRetry && mAdConfigList.isNotEmpty()) {
if (isFromRetry && mAdConfigList != null) {
return
}
val paramsMap = if (keyword.isNotEmpty()) mapOf("keyword" to keyword) else mapOf()
@ -135,7 +129,7 @@ object AdDelegateHelper {
// 若接口请求失败时,从 SP 里获取上次缓存的数据
val cachedConfig: List<AdConfig>? = SPUtils.getString(mAdConfigSp, KEY_CACHE_CONFIG).toObject()
if (cachedConfig != null && mAdConfigList.isEmpty()) {
if (cachedConfig != null) {
handleAdConfig(cachedConfig)
}
@ -162,13 +156,11 @@ object AdDelegateHelper {
* 处理广告配置
*/
fun handleAdConfig(configList: List<AdConfig>) {
mAdConfigList.clear()
mGameSearchAdList.clear()
mSplashAd = null
mDownloadManagerAd = null
mVGameLaunchAd = null
for (config in configList) {
mAdConfigList.add(config)
// 处理返回的数据
when (config.location) {
"halo_launch" -> {
@ -196,11 +188,9 @@ object AdDelegateHelper {
}
/**
* 热启动是否需要显示开屏广告(目前只展示第三方广告)
* 热启动是否需要显示开屏广告
*/
private fun shouldShowStartUpAdWhenHotLaunch() = (mCsjAdImpl != null)
&& mSplashAd?.displayRule?.hotStartSplashAd?.type == AD_TYPE_SDK
&& mSplashAd?.hotStartThirdPartyAd != null
private fun shouldShowStartUpAdWhenHotLaunch() = mSplashAd?.displayRule?.hotStartSplashAd?.type == AD_TYPE_SDK
/**
* 是否需要显示下载管理广告
@ -209,10 +199,6 @@ object AdDelegateHelper {
return mDownloadManagerAd != null && !isMatchAdFreeRule(mDownloadManagerAd) && isMatchDownloadManagerAdDisplayRule()
}
fun shouldShowHelperLaunchAd(): Boolean {
return mVGameLaunchAd != null && !isMatchAdFreeRule(mVGameLaunchAd) && isMatchAdDisplayRule(mVGameLaunchAd, Constants.SP_LAST_HELPER_LAUNCH_AD_SHOW_TIME)
}
/**
* 是否需要显示游戏搜索广告
*/
@ -241,16 +227,26 @@ object AdDelegateHelper {
/**
* 是否大于开屏广告展示间隔时长
*/
private fun isMatchStartUpAdDisplayRule(): Boolean = isMatchAdDisplayRule(mSplashAd, Constants.SP_LAST_SPLASH_AD_SHOW_TIME)
private fun isMatchStartUpAdDisplayRule(): Boolean {
mSplashAd?.displayRule?.run {
if (adDisplayInterval > 0) {
val lastShowTime = SPUtils.getLong(Constants.SP_LAST_SPLASH_AD_SHOW_TIME, 0L)
val durationInMinutes = (System.currentTimeMillis() - lastShowTime).toFloat() / 1000 / 60
return durationInMinutes > adDisplayInterval
} else {
return true
}
}
return true
}
/**
* 是否大于广告管理展示间隔时长
*/
private fun isMatchDownloadManagerAdDisplayRule(): Boolean = isMatchAdDisplayRule(mDownloadManagerAd, Constants.SP_LAST_DOWNLOAD_MANAGER_AD_SHOW_TIME)
private fun isMatchAdDisplayRule(adConfig: AdConfig?, spKey: String): Boolean {
adConfig?.displayRule?.run {
private fun isMatchDownloadManagerAdDisplayRule(): Boolean {
mDownloadManagerAd?.displayRule?.run {
if (adDisplayInterval > 0) {
val lastShowTime = SPUtils.getLong(spKey, 0L)
val lastShowTime = SPUtils.getLong(Constants.SP_LAST_DOWNLOAD_MANAGER_AD_SHOW_TIME, 0L)
val durationInMinutes = (System.currentTimeMillis() - lastShowTime).toFloat() / 1000 / 60
return durationInMinutes > adDisplayInterval
} else {
@ -295,7 +291,6 @@ object AdDelegateHelper {
adViewHeightInDp: Float,
startAdContainer: ViewGroup,
sdkStartAdContainer: ViewGroup,
sdkJumpBtn: TextView,
adsViewGroup: FrameLayout,
handler: BaseActivity.BaseHandler,
isHotLaunch: Boolean,
@ -317,7 +312,6 @@ object AdDelegateHelper {
adViewHeightInDp,
startAdContainer,
sdkStartAdContainer,
sdkJumpBtn,
adsViewGroup,
handler,
isHotLaunch,
@ -335,7 +329,6 @@ object AdDelegateHelper {
adViewHeightInDp,
startAdContainer,
sdkStartAdContainer,
sdkJumpBtn,
adsViewGroup,
handler,
isHotLaunch,
@ -359,12 +352,16 @@ object AdDelegateHelper {
adViewHeightInDp: Float,
startAdContainer: ViewGroup,
sdkStartAdContainer: ViewGroup,
sdkJumpBtn: TextView,
adsViewGroup: FrameLayout,
handler: BaseActivity.BaseHandler,
isHotLaunch: Boolean,
hideCallback: () -> Unit
) {
val timeout = if (isHotLaunch) {
((mSplashAd!!.displayRule.hotStartSplashAd?.timeout ?: 3.5F) * 1000).toInt()
} else {
(mSplashAd!!.displayRule.timeout * 1000).toInt()
}
// 第三方开屏广告回调,失败时根据接口配置选项决定是否显示自有开屏广告
val sdkSplashCallback: (isSuccess: Boolean) -> Unit = { isSuccess ->
if (isSuccess) {
@ -381,7 +378,6 @@ object AdDelegateHelper {
adViewHeightInDp,
startAdContainer,
sdkStartAdContainer,
sdkJumpBtn,
adsViewGroup,
handler,
isHotLaunch,
@ -393,32 +389,26 @@ object AdDelegateHelper {
}
}
val thirdPartyAd = if (isHotLaunch) mSplashAd?.hotStartThirdPartyAd else mSplashAd?.thirdPartyAd
// 第三方广告的数据为空,按加载失败处理
if (mSplashAd == null || thirdPartyAd == null) {
if (mSplashAd?.thirdPartyAd == null) {
sdkSplashCallback.invoke(false)
return
}
val timeout = if (isHotLaunch) {
((mSplashAd?.displayRule?.hotStartSplashAd?.timeout ?: 3.5F) * 1000).toInt()
} else {
((mSplashAd?.displayRule?.timeout ?: 3.5F) * 1000).toInt()
}
if (thirdPartyAd.sourceName == AD_SDK_CSJ) {
if (mSplashAd?.thirdPartyAd?.sourceName == AD_SDK_BEIZI) {
sdkStartAdContainer.visibility = View.VISIBLE
requestBeiziSplashAd(sdkStartAdContainer, adsViewGroup, adViewWidthInPx, adViewHeightInPx, timeout.toLong(), sdkSplashCallback)
} else if (mSplashAd?.thirdPartyAd?.sourceName == AD_SDK_CSJ) {
sdkStartAdContainer.visibility = View.VISIBLE
requestCsjSplashAd(
activity,
mSplashAd?.thirdPartyAd?.slotId ?: "unknown",
adViewWidthInPx,
adViewHeightInPx,
adViewWidthInDp,
adViewHeightInDp,
sdkStartAdContainer,
sdkJumpBtn,
timeout,
isHotLaunch,
sdkSplashCallback
)
}
@ -429,70 +419,50 @@ object AdDelegateHelper {
*/
private fun requestCsjSplashAd(
activity: Activity,
slotId: String,
adViewWidthInPx: Int,
adViewHeightInPx: Int,
adViewWidthInDp: Float,
adViewHeightInDp: Float,
startAdContainer: ViewGroup,
sdkJumpBtn: TextView,
timeout: Int,
isHotLaunch: Boolean,
callback: (isSuccess: Boolean) -> Unit,
) {
val thirdPartyAd = if (isHotLaunch) mSplashAd?.hotStartThirdPartyAd else mSplashAd?.thirdPartyAd
if (mCsjAdImpl == null || thirdPartyAd == null) {
if (mCsjAdImpl == null) {
callback.invoke(false)
} else {
sdkJumpBtn.setOnClickListener {
callback.invoke(true)
if (activity is BaseActivity) {
activity.baseHandler.removeMessages(MainActivity.COUNTDOWN_SDK_AD)
}
}
val onAdShowAction = {
sdkJumpBtn.visibility = View.VISIBLE
if (activity is BaseActivity) {
activity.baseHandler.sendEmptyMessageDelayed(MainActivity.COUNTDOWN_SDK_AD, 1000)
}
SensorsBridge.trackEvent("ThirdPartyAdShow",
"ad_source", thirdPartyAd.sourceName,
"ad_id", thirdPartyAd.slotId,
"ad_format", mSplashAd?.typeChinese ?: "",
"ad_placement", "光环启动",
"launch_type", if (isHotLaunch) "热启动" else "冷启动",
"ad_space_id", mSplashAd?.id ?: "",
"ad_space_name", mSplashAd?.name ?: ""
)
}
val onAdClickAction = {
callback.invoke(true)
SensorsBridge.trackEvent("ThirdPartyAdClick",
"ad_source", thirdPartyAd.sourceName,
"ad_id", thirdPartyAd.slotId,
"ad_format", mSplashAd?.typeChinese ?: "",
"ad_placement", "光环启动",
"launch_type", if (isHotLaunch) "热启动" else "冷启动",
"ad_space_id", mSplashAd?.id ?: "",
"ad_space_name", mSplashAd?.name ?: ""
)
}
mCsjAdImpl?.requestSplashAd(
activity,
thirdPartyAd.slotId,
slotId,
adViewWidthInPx,
adViewHeightInPx,
adViewWidthInDp,
adViewHeightInDp,
startAdContainer,
timeout,
onAdShowAction,
onAdClickAction,
callback,
)
}
}
/**
* 获取 Beizi 的开屏广告
*/
private fun requestBeiziSplashAd(
startAdContainer: View,
adsFl: FrameLayout,
adViewWidthInPx: Int,
adViewHeightInPx: Int,
timeout: Long,
callback: (isSuccess: Boolean) -> Unit,
) {
if (mBeiziAdImpl == null) {
callback.invoke(false)
} else {
mBeiziAdImpl?.requestSplashAd(startAdContainer, adsFl, adViewWidthInPx, adViewHeightInPx, timeout, callback)
}
}
/**
* 显示自有的开屏广告
*/
@ -504,7 +474,6 @@ object AdDelegateHelper {
adViewHeightInDp: Float,
startAdContainer: ViewGroup,
sdkStartAdContainer: ViewGroup,
sdkJumpBtn: TextView,
adsViewGroup: FrameLayout,
handler: BaseActivity.BaseHandler,
isHotLaunch: Boolean,
@ -522,7 +491,6 @@ object AdDelegateHelper {
adViewHeightInDp,
startAdContainer,
sdkStartAdContainer,
sdkJumpBtn,
adsViewGroup,
handler,
isHotLaunch,
@ -575,15 +543,12 @@ object AdDelegateHelper {
handler: BaseActivity.BaseHandler,
hideCallback: () -> Unit
) {
val jumpBtn = startAdContainer.findViewById<TextView>(R.id.jumpBtn)
val jumpBtn: View = startAdContainer.findViewById(R.id.jumpBtn)
val jumpDetailBtn: TextView = startAdContainer.findViewById(R.id.jumpDetailBtn)
val adImage: SimpleDraweeView = startAdContainer.findViewById(R.id.adImage)
val adVideo = startAdContainer.findViewById<SplashAdVideoView>(R.id.ad_video)
val icpContainer: View? = startAdContainer.findViewById(R.id.startAdIcpContainer)
startAdContainer.visibility = View.VISIBLE
icpContainer?.visibility = View.VISIBLE
jumpBtn.text = startAdContainer.context.getString(R.string.splash_jump, splashAdDisplayInterval)
jumpDetailBtn.text = ad.desc
jumpDetailBtn.setDrawableEnd(
AppCompatResources.getDrawable(
@ -591,16 +556,7 @@ object AdDelegateHelper {
R.drawable.ic_startup_ad_arrow
), null, null
)
adImage.visibleIf(true)
ImageUtils.display(adImage, ad.img)
if (ad.isImageType) {
adVideo.visibleIf(false)
} else {
adVideo.visibleIf(true)
adVideo.startPlay(ad.video.url)
}
startAdContainer.setOnClickListener {
// 拦截点击事件传递
}
@ -614,17 +570,6 @@ object AdDelegateHelper {
(if (linkEntity.type != null) linkEntity.type else "")!!,
(if (linkEntity.link != null) linkEntity.link else "")!!
)
SensorsBridge.trackEvent(
"SplashAdOwnSkip",
"splash_ad_id",
ad.id,
"link_type",
linkEntity.type ?: "",
"link_id",
linkEntity.link ?: "",
"link_text",
linkEntity.text ?: ""
)
}
val sources: MutableList<ExposureSource> = ArrayList()
sources.add(ExposureSource("开屏广告", ad.id))
@ -632,19 +577,7 @@ object AdDelegateHelper {
ExposureManager.log(event)
if (ad.button) {
jumpDetailBtn.setOnClickListener { v: View ->
val linkEntity = ad.jump
directToLinkPage(v.context, linkEntity, "(启动广告)", "", event)
SensorsBridge.trackEvent(
"SplashAdOwnClick",
"splash_ad_id",
ad.id,
"link_type",
linkEntity.type ?: "",
"link_id",
linkEntity.link ?: "",
"link_text",
linkEntity.text ?: ""
)
directToLinkPage(v.context, ad.jump, "(启动广告)", "", event)
v.postDelayed({
handler.removeMessages(MainActivity.COUNTDOWN_AD)
hideCallback.invoke()
@ -656,10 +589,7 @@ object AdDelegateHelper {
LogUtils.logStartAd("start_ads", ad)
}
SPUtils.setLong(Constants.SP_LAST_SPLASH_AD_SHOW_TIME, System.currentTimeMillis())
val msg = Message.obtain()
msg.what = MainActivity.COUNTDOWN_AD
msg.obj = ad
handler.sendMessageDelayed(msg, 1000)
handler.sendEmptyMessageDelayed(MainActivity.COUNTDOWN_AD, 1000)
}
/**
@ -670,11 +600,9 @@ object AdDelegateHelper {
slotId: String,
adContainerView: ViewGroup,
expressViewWidth: Float,
onAdShowAction: () -> Unit,
onAdClickAction: () -> Unit,
callback: (isSuccess: Boolean) -> Unit,
) {
mCsjAdImpl?.requestFlowAd(fragment, adContainerView, slotId, expressViewWidth, onAdShowAction, onAdClickAction, callback)
mCsjAdImpl?.requestFlowAd(fragment, adContainerView, slotId, expressViewWidth, callback)
}
/**
@ -685,8 +613,6 @@ object AdDelegateHelper {
containerView: ViewGroup,
ad: AdConfig.ThirdPartyAd,
expressViewWidthInDp: Float,
onAdShowAction: () -> Unit,
onAdClickAction: () -> Unit,
callback: (isSuccess: Boolean) -> Unit
) {
@ -709,28 +635,6 @@ object AdDelegateHelper {
slotId,
expressViewWidthInDp,
expressViewHeightInDp,
onAdShowAction,
onAdClickAction,
callback
)
}
/**
* 获取第三方 全屏/插屏 广告
*/
fun requestFullScreenAd(
fragment: Fragment,
ad: AdConfig.ThirdPartyAd,
onAdShowAction: () -> Unit,
onAdClickAction: () -> Unit,
callback: (isSuccess: Boolean) -> Unit
) {
val slotId = ad.slotId
mCsjAdImpl?.requestFullScreenAd(
fragment,
slotId,
onAdShowAction,
onAdClickAction,
callback
)
}
@ -739,6 +643,7 @@ object AdDelegateHelper {
* 取消开屏广告
*/
fun cancelSplashAd(context: Context) {
mBeiziAdImpl?.cancelSplashAd(context)
mCsjAdImpl?.cancelSplashAd(context)
}

View File

@ -1,149 +0,0 @@
package com.gh.ad
import com.gh.download.simple.DownloadMessageHandler
import com.gh.download.simple.SimpleDownloadDatabase
import com.gh.download.simple.SimpleDownloadManager
import com.gh.gamecenter.core.runOnIoThread
import com.gh.gamecenter.core.utils.PluginRedirectHelper
import com.gh.gamecenter.core.utils.SPUtils
import com.lg.download.DownloadError
import com.lg.download.DownloadStatus
import com.lg.download.httpclient.DefaultHttpClient
import com.lg.download.listener.InnerDownloadListener
import com.lg.ndownload.DownloadConfig
import com.lg.ndownload.DownloadConfigBuilder
import com.lg.ndownload.DownloadIoExecutor
import com.lightgame.utils.Utils
import java.lang.Exception
import java.net.URLConnection
object AdPluginDownloadHelper : InnerDownloadListener {
private const val CSJ_FILE_NAME = "2011394667"
private const val GDT_FILE_NAME = "gdt_plugin/gdtadv2.jar"
private const val CSJ_PLUGIN_URL = "https://and-static.ghzs66.com/android/static/2011394667"
private const val GDT_PLUGIN_URL = "https://and-static.ghzs66.com/android/static/gdtadv2.jar"
private var csjDownloadedCallback: (() -> Unit)? = null
/**
* 是否已经下载了广告插件
*/
fun isCsjPluginDownloaded(): Boolean {
return SPUtils.getBoolean(CSJ_FILE_NAME, false)
}
/**
* 下载广告插件并初始化 (初始化限定穿山甲)
*/
fun downloadPluginIfNeeded(isCsj: Boolean = false, isGdt: Boolean = false, csjCallback: (() -> Unit)? = null) {
val isCsjPluginDownloaded = SPUtils.getBoolean(CSJ_FILE_NAME, false)
val isGdtPluginDownloaded = SPUtils.getBoolean(GDT_FILE_NAME, false)
if (isCsj && isCsjPluginDownloaded) {
csjCallback?.invoke()
return
}
if (isGdt && isGdtPluginDownloaded) {
return
}
runOnIoThread {
csjDownloadedCallback = csjCallback
DownloadMessageHandler.init(SimpleDownloadDatabase.instance.downloadDao())
if (!isCsjPluginDownloaded && isCsj) {
val csjPluginConfig = DownloadConfigBuilder()
.setUniqueId(CSJ_FILE_NAME)
.setUrl(CSJ_PLUGIN_URL)
.setFileName(CSJ_FILE_NAME)
.setHttpClient(DefaultHttpClient())
.setDownloadThreadSize(2)
.setPathToStore(PluginRedirectHelper.getAssetDir())
.setDownloadExecutor(DownloadIoExecutor.getInstance())
.setDownloadListener(this).build()
SimpleDownloadManager.download(csjPluginConfig)
}
if (!isGdtPluginDownloaded && isGdt) {
val gdtPluginConfig = DownloadConfigBuilder()
.setUniqueId(GDT_FILE_NAME)
.setUrl(GDT_PLUGIN_URL)
.setFileName(GDT_FILE_NAME)
.setHttpClient(DefaultHttpClient())
.setDownloadThreadSize(2)
.setPathToStore(PluginRedirectHelper.getAssetDir())
.setDownloadExecutor(DownloadIoExecutor.getInstance())
.setDownloadListener(this).build()
SimpleDownloadManager.download(gdtPluginConfig)
}
}
}
override fun onError(id: String?, error: DownloadError?, exception: Exception?) {
Utils.log("下载广告插件失败 $id")
id?.let {
if (it == CSJ_FILE_NAME) {
csjDownloadedCallback = null
}
SimpleDownloadManager.cancel(it)
}
}
override fun onProgress(id: String?, progress: Float) {
Utils.log("下载广告插件进度 $id $progress")
}
override fun onProgressWithoutThrottle(id: String?, progress: Float) {
// do nothing
}
override fun onSizeReceived(id: String?, fileSize: Long) {
// do nothing
}
override fun onReadyToDownload(id: String?, actualThreadSize: Int) {
// do nothing
}
override fun onStatusChanged(id: String?, status: DownloadStatus?) {
// do nothing
}
override fun onDownloadComplete(id: String?, elapsedTime: Long) {
id?.let {
// id 即为插件名
SPUtils.setBoolean(it, true)
if (it == CSJ_FILE_NAME) {
csjDownloadedCallback?.invoke()
csjDownloadedCallback = null
}
}
}
override fun onSpeedChanged(id: String?, speed: Float) {
// do nothing
}
override fun onRedirectingUrl(
id: String?,
connection: URLConnection?,
config: DownloadConfig?
) {
// do nothing
}
override fun onRedirectedUrl(
id: String?,
connection: URLConnection?,
redirectedUrl: String?
) {
// do nothing
}
}

View File

@ -1,107 +0,0 @@
package com.gh.ad
import android.content.Context
import android.view.View
import android.view.ViewGroup
import android.view.ViewStub
import androidx.fragment.app.Fragment
import com.alibaba.android.arouter.facade.annotation.Route
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.common.provider.ILaunchAd
import com.gh.gamecenter.common.utils.SensorsBridge
import com.gh.gamecenter.common.utils.goneIf
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.entity.AdConfig
@Route(path = RouteConsts.provider.vaAd, name = "畅玩启动页广告")
class LaunchAdImpl : ILaunchAd {
override fun init(context: Context?) {
}
override fun requestAd(fragment: Fragment, container: ViewGroup, maskView: View, topViewStub: ViewStub, bottomViewStub: ViewStub, adClickAction: () -> Unit): View {
if (AdDelegateHelper.shouldShowHelperLaunchAd()) {
val launchAd = AdDelegateHelper.vGameLaunchAd
val showThirdPartyAd = launchAd?.displayRule?.adSource == AdDelegateHelper.AD_TYPE_SDK
val thirdPartyAd = launchAd?.thirdPartyAd
if (showThirdPartyAd && thirdPartyAd != null) {
val onAdShowAction = {
SensorsBridge.trackEvent("ThirdPartyAdShow",
"ad_source", thirdPartyAd.sourceName,
"ad_id", thirdPartyAd.slotId,
"ad_format", launchAd.typeChinese,
"ad_placement", AD_PLACEMENT,
"ad_space_id", launchAd.id,
"ad_space_name", launchAd.name
)
}
val onAdClickAction = {
SensorsBridge.trackEvent("ThirdPartyAdClick",
"ad_source", thirdPartyAd.sourceName,
"ad_id", thirdPartyAd.slotId,
"ad_format", launchAd.typeChinese,
"ad_placement", AD_PLACEMENT,
"ad_space_id", launchAd.id,
"ad_space_name", launchAd.name
)
adClickAction.invoke()
}
if (launchAd.type == AdConfig.TYPE_BANNER) {
requestBannerAd(fragment, container, maskView, thirdPartyAd, onAdShowAction, onAdClickAction)
return topViewStub.inflate()
} else if (launchAd.type == AdConfig.TYPE_INTERSTITIAL) {
requestFullScreenAd(fragment, thirdPartyAd, onAdShowAction, onAdClickAction)
return bottomViewStub.inflate()
}
}
}
return bottomViewStub.inflate()
}
private fun requestBannerAd(
fragment: Fragment,
container: ViewGroup,
maskView: View,
thirdPartyAd: AdConfig.ThirdPartyAd,
onAdShowAction: () -> Unit,
onAdClickAction: () -> Unit,
) {
AdDelegateHelper.requestThirdPartyBannerAd(
fragment,
container,
thirdPartyAd,
DisplayUtils.getScreenWidthInDp(fragment.requireActivity()),
onAdShowAction,
onAdClickAction
) { isSuccess ->
maskView.goneIf(!isSuccess)
if (isSuccess) {
SPUtils.setLong(Constants.SP_LAST_HELPER_LAUNCH_AD_SHOW_TIME, System.currentTimeMillis())
}
}
}
private fun requestFullScreenAd(
fragment: Fragment,
thirdPartyAd: AdConfig.ThirdPartyAd,
onAdShowAction: () -> Unit,
onAdClickAction: () -> Unit
) {
AdDelegateHelper.requestFullScreenAd(
fragment,
thirdPartyAd,
onAdShowAction,
onAdClickAction
) { isSuccess ->
if (isSuccess) {
SPUtils.setLong(Constants.SP_LAST_HELPER_LAUNCH_AD_SHOW_TIME, System.currentTimeMillis())
}
}
}
companion object {
private const val AD_PLACEMENT = "畅玩启动"
}
}

View File

@ -1,78 +0,0 @@
package com.gh.ad
import android.app.Activity
import android.content.Context
import android.util.AttributeSet
import android.view.WindowManager
import com.gh.gamecenter.R
import com.gh.gamecenter.video.detail.CustomManager
import com.shuyu.gsyvideoplayer.utils.GSYVideoType
import com.shuyu.gsyvideoplayer.utils.GSYVideoType.SCREEN_TYPE_FULL
import com.shuyu.gsyvideoplayer.video.StandardGSYVideoPlayer
import com.shuyu.gsyvideoplayer.video.base.GSYVideoViewBridge
class SplashAdVideoView @JvmOverloads constructor(
context: Context,
attrs: AttributeSet? = null
) :
StandardGSYVideoPlayer(context, attrs) {
fun startPlay(url: String) {
GSYVideoType.setShowType(SCREEN_TYPE_FULL)
GSYVideoType.setRenderType(GSYVideoType.SUFRACE)
CustomManager.getCustomManager(getKey()).isNeedMute = true
setUp(url, true, "")
setNeedAutoAdaptation(false)
startPlayLogic()
}
override fun getGSYVideoManager(): GSYVideoViewBridge {
CustomManager.getCustomManager(getKey()).initContext(context.applicationContext)
return CustomManager.getCustomManager(getKey())
}
private fun getKey() = "splash_ad"
/**
* 覆盖父类方法,防止在是视频 Preparing 阶段封面图被隐藏,导致白屏
*/
override fun changeUiToPreparingShow() = Unit
override fun getLayoutId(): Int {
return R.layout.layout_splash_ad_video
}
override fun onAutoCompletion() {
setStateAndUi(CURRENT_STATE_AUTO_COMPLETE);
mSaveChangeViewTIme = 0
mCurrentPosition = 0
if (!mIfCurrentIsFullscreen) {
getGSYVideoManager().setLastListener(null)
}
mAudioManager.abandonAudioFocus(onAudioFocusChangeListener);
if (mContext is Activity) {
try {
(mContext as Activity).getWindow().clearFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON)
} catch (e: Exception) {
e.printStackTrace()
}
}
releaseNetWorkState()
if (mVideoAllCallBack != null && isCurrentMediaListener()) {
mVideoAllCallBack.onAutoComplete(mOriginUrl, mTitle, this)
}
mHadPlay = false
}
fun clearAll() {
GSYVideoType.setShowType(GSYVideoType.SCREEN_TYPE_DEFAULT)
GSYVideoType.setRenderType(GSYVideoType.TEXTURE)
release()
CustomManager.removeManager(getKey())
}
}

View File

@ -21,8 +21,6 @@ import com.gh.common.view.RichEditor
import com.gh.gamecenter.CropImageActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.activity.ToolBarActivity
import com.gh.gamecenter.common.entity.LocalVideoEntity
import com.gh.gamecenter.feature.selector.LocalMediaActivity
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.AppExecutor
import com.gh.gamecenter.core.runOnIoThread
@ -32,7 +30,6 @@ import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.qa.editor.*
import com.gh.gamecenter.feature.entity.AnswerEntity
import com.gh.gamecenter.feature.entity.ArticleEntity
import com.gh.gamecenter.feature.selector.ChooseType
import com.gh.gamecenter.qa.entity.EditorInsertEntity
import com.gh.gamecenter.video.poster.PosterEditActivity
import com.gh.gamecenter.video.upload.UploadManager
@ -47,7 +44,7 @@ import org.json.JSONObject
import java.io.File
// TODO: 移动到module_bbs模块
abstract class BaseRichEditorActivity<VM : BaseRichEditorViewModel> constructor() : ToolBarActivity(),
abstract class BaseRichEditorActivity<VM : BaseRichEditorViewModel> : ToolBarActivity(),
KeyboardHeightObserver, UploadVideoListener {
lateinit var mRichEditor: RichEditor
@ -236,7 +233,7 @@ abstract class BaseRichEditorActivity<VM : BaseRichEditorViewModel> constructor(
mKeyboardHeightProvider = KeyboardHeightProvider(this)
mRichEditor.post { mKeyboardHeightProvider?.start() }
mRichEditor.enableForceDark(DarkModeUtils.isDarkModeOn(this))
mRichEditor.setEditorBackgroundColor(com.gh.gamecenter.common.R.color.ui_surface.toColor(this))
mRichEditor.setEditorBackgroundColor(R.color.ui_surface.toColor(this))
mRichEditor.setEditorFontColor(if (mIsDarkModeOn) Color.parseColor("#C2C2C2") else Color.parseColor("#4A4A4A"))
// 防止个别手机在Js里无法获取粘贴内容
mRichEditor.addJavascriptInterface(OnPasteListener(), "onPasteListener")
@ -505,7 +502,7 @@ abstract class BaseRichEditorActivity<VM : BaseRichEditorViewModel> constructor(
startActivityForResult(
LocalMediaActivity.getIntent(
this@BaseRichEditorActivity,
ChooseType.VIDEO,
LocalMediaActivity.ChooseType.VIDEO,
maxChooseCount,
if (mtaEventName() == "提问帖") "发提问帖" else "发帖子"
), INSERT_MEDIA_VIDEO_CODE
@ -534,7 +531,7 @@ abstract class BaseRichEditorActivity<VM : BaseRichEditorViewModel> constructor(
val maxChooseCount = if (imageCount + 10 <= MAX_IMAGE_COUNT) 10 else MAX_IMAGE_COUNT - imageCount
val intent = LocalMediaActivity.getIntent(
this@BaseRichEditorActivity,
ChooseType.IMAGE,
LocalMediaActivity.ChooseType.IMAGE,
maxChooseCount,
if (mtaEventName() == "提问帖") "发提问帖" else "发帖子"
)
@ -800,9 +797,9 @@ abstract class BaseRichEditorActivity<VM : BaseRichEditorViewModel> constructor(
override fun onDarkModeChanged() {
super.onDarkModeChanged()
updateStatusBarColor(com.gh.gamecenter.common.R.color.ui_surface, com.gh.gamecenter.common.R.color.ui_surface)
updateStatusBarColor(R.color.ui_surface, R.color.ui_surface)
mRichEditor.enableForceDark(DarkModeUtils.isDarkModeOn(this))
mRichEditor.setEditorBackgroundColor(com.gh.gamecenter.common.R.color.ui_surface.toColor(this))
mRichEditor.setEditorBackgroundColor(R.color.ui_surface.toColor(this))
mRichEditor.setEditorFontColor(if (mIsDarkModeOn) Color.parseColor("#C2C2C2") else Color.parseColor("#4A4A4A"))
}

View File

@ -10,16 +10,17 @@ import android.text.TextUtils
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.MediatorLiveData
import androidx.lifecycle.MutableLiveData
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.fragment.WaitingDialogFragment
import com.gh.gamecenter.common.entity.ErrorEntity
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.common.retrofit.Response
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.runOnUiThread
import com.gh.gamecenter.core.utils.MD5Utils
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.common.entity.ErrorEntity
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.entity.ForumDetailEntity
import com.gh.gamecenter.common.entity.LocalVideoEntity
import com.gh.gamecenter.entity.LocalVideoEntity
import com.gh.gamecenter.entity.QuoteCountEntity
import com.gh.gamecenter.qa.BbsType
import com.gh.gamecenter.retrofit.RetrofitManager
@ -27,6 +28,7 @@ import com.gh.gamecenter.retrofit.service.ApiService
import com.gh.gamecenter.video.upload.OnUploadListener
import com.gh.gamecenter.video.upload.UploadManager
import com.google.gson.JsonObject
import com.lightgame.download.FileUtils
import com.lightgame.utils.Utils
import com.zhihu.matisse.Matisse
import com.zhihu.matisse.internal.utils.PathUtils
@ -38,6 +40,8 @@ import retrofit2.HttpException
import java.io.File
import java.io.FileOutputStream
import java.util.*
import kotlin.collections.ArrayList
import kotlin.collections.HashMap
import kotlin.collections.LinkedHashMap
import kotlin.collections.set
@ -58,6 +62,7 @@ abstract class BaseRichEditorViewModel(application: Application) : AndroidViewMo
val TITLE_MIN_LENGTH = 6
val MIN_TEXT_LENGTH = 6
val MAX_TEXT_LENGTH = 10000
val FILE_HOST = "file:///"
var id = ""//视频标记
var videoId = ""//更改封面视频id
val quoteCountEntity = QuoteCountEntity()//数据上报用
@ -83,7 +88,7 @@ abstract class BaseRichEditorViewModel(application: Application) : AndroidViewMo
val application: Application = getApplication()
Utils.toast(
getApplication(),
application.getString(com.gh.gamecenter.common.R.string.pic_max_hint, count)
application.getString(R.string.pic_max_hint, count)
)
continue
}
@ -124,13 +129,15 @@ abstract class BaseRichEditorViewModel(application: Application) : AndroidViewMo
}
val map = LinkedHashMap<String, String>()
for (key in imageUrlMap.keys) {
val localFileUri = FILE_HOST + key.decodeURI()
// 文件格式为 HEIC 时,使用经 OSS 转码的图片作为预览图片
if (FileUtils.getFileMimeType(getApplication(), key.decodeURI())?.lowercase(Locale.CHINA)?.contains("heic") == true) {
val transformedImgUrl = ImageUtils.getIdealImageUrl(imageUrlMap[key], 5000) ?: ""
val transformedImgUrl = ImageUtils.getTransformedUrl(imageUrlMap[key], 5000) ?: ""
map[MD5Utils.getUrlMD5(key)] = transformedImgUrl
mapImages[transformedImgUrl.decodeURI()] = imageUrlMap[key] ?: ""
} else {
map[MD5Utils.getUrlMD5(key)] = imageUrlMap[key] ?: ""
map[MD5Utils.getUrlMD5(key)] = localFileUri
mapImages[TextUtils.htmlEncode(key).decodeURI()] = imageUrlMap[key] ?: ""
}
}

View File

@ -46,7 +46,7 @@ abstract class DownloadToolbarActivity : ToolBarActivity() {
override fun inflateMenu(res: Int) {
super.inflateMenu(res)
if (!getBoolean(Constants.SP_TEENAGER_MODE) && showDownloadMenu()) {
if (showDownloadMenu()) {
createDownloadMenu(res)
}
}
@ -60,7 +60,7 @@ abstract class DownloadToolbarActivity : ToolBarActivity() {
}
val downloadMenuView = mActionMenuView.menu.findItem(R.id.menu_download).actionView
mDownloadCountHint = downloadMenuView?.findViewById(R.id.menu_download_count_hint)
mDownloadCountHint?.typeface = Typeface.createFromAsset(assets, Constants.DIN_FONT_PATH)
mDownloadCountHint?.typeface = Typeface.createFromAsset(assets, "fonts/d_din_bold_only_number.ttf")
}
override fun onMenuItemClick(item: MenuItem?): Boolean {

View File

@ -4,7 +4,6 @@ import android.app.Activity
import android.app.Application
import android.os.Bundle
import androidx.appcompat.app.AppCompatActivity
import com.alibaba.android.arouter.launcher.ARouter
import com.gh.ad.AdDelegateHelper
import com.gh.common.util.FloatingBackViewManager
import com.gh.common.xapk.XapkInstaller
@ -15,19 +14,14 @@ import com.gh.gamecenter.SplashAdActivity
import com.gh.gamecenter.SplashScreenActivity
import com.gh.gamecenter.authorization.AuthorizationActivity
import com.gh.gamecenter.common.base.GlobalActivityManager
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.common.provider.IHelpAndFeedbackProvider
import com.gh.gamecenter.common.utils.PackageFlavorHelper
import com.gh.gamecenter.core.provider.IPushProvider
import com.gh.gamecenter.login.view.LoginActivity
import com.gh.gamecenter.va.VCore
import com.gh.gamecenter.login.utils.QuickLoginHelper
import com.gh.vspace.VHelper
import com.halo.assistant.HaloApp
// TODO移动到对应的模块
class GlobalActivityLifecycleObserver : Application.ActivityLifecycleCallbacks {
private var isFromBackgroundToForeground = false // 是否后台回到前台
private var activityCount = 0
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {
// do nothing
@ -35,31 +29,19 @@ class GlobalActivityLifecycleObserver : Application.ActivityLifecycleCallbacks {
override fun onActivityStarted(activity: Activity) {
GlobalActivityManager.currentActivity = activity
GlobalActivityManager.activityCount ++
if (GlobalActivityManager.activityCount == 1 && isFromBackgroundToForeground) {
activityCount ++
if (activityCount == 1 && isFromBackgroundToForeground) {
if (AdDelegateHelper.shouldShowStartUpAd(true)
&& !HaloApp.getInstance().isDisableSplashAdTemporarily
&& !HaloApp.getInstance().isSkippingThirdParty
&& activity !is SplashScreenActivity
&& activity !is SkipActivity
&& activity !is AuthorizationActivity
&& activity !is SplashAdActivity
&& !isSuggestionActivity(activity)
) {
activity.startActivity(SplashAdActivity.getIntent(activity))
}
isFromBackgroundToForeground = false
}
if (GlobalActivityManager.activityCount == 1) {
// 清除桌面角标
if (activity !is SplashScreenActivity && activity !is AuthorizationActivity) {
val pushProvider = ARouter.getInstance().build(RouteConsts.provider.push).navigation() as? IPushProvider
pushProvider?.cleanBadgeNumber(activity.applicationContext)
}
}
if (QuickLoginHelper.isLoginAuthPage(activity)) {
QuickLoginHelper.addCustomViewToLoginAuthPage(activity)
}
}
override fun onActivityResumed(activity: Activity) {
@ -91,8 +73,6 @@ class GlobalActivityLifecycleObserver : Application.ActivityLifecycleCallbacks {
}
if (activity is AppCompatActivity
&& !VCore.getInstance().isLaunchActivity(activity)
&& activity !is LoginActivity
&& activity !is SplashScreenActivity
&& activity !is SkipActivity
&& activity !is AuthorizationActivity
@ -111,8 +91,8 @@ class GlobalActivityLifecycleObserver : Application.ActivityLifecycleCallbacks {
}
override fun onActivityStopped(activity: Activity) {
GlobalActivityManager.activityCount --
isFromBackgroundToForeground = GlobalActivityManager.activityCount <= 0
activityCount --
isFromBackgroundToForeground = activityCount <= 0
}
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {
@ -120,16 +100,7 @@ class GlobalActivityLifecycleObserver : Application.ActivityLifecycleCallbacks {
}
override fun onActivityDestroyed(activity: Activity) {
if (QuickLoginHelper.isLoginAuthPage(activity)) {
QuickLoginHelper.release()
}
}
private fun isSuggestionActivity(activity: Activity): Boolean {
val helpAndFeedbackProvider =
ARouter.getInstance().build(RouteConsts.provider.helpAndFeedback)
.navigation() as? IHelpAndFeedbackProvider
return helpAndFeedbackProvider?.isSuggestionActivity(activity) ?: false
// do nothing
}
}

View File

@ -32,13 +32,9 @@ import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.utils.NewFlatLogUtils
import com.gh.gamecenter.common.view.dsbridge.CompletionHandler
import com.gh.gamecenter.core.AppExecutor
import com.gh.gamecenter.core.provider.IPushProvider
import com.gh.gamecenter.core.runOnIoThread
import com.gh.gamecenter.core.runOnUiThread
import com.gh.gamecenter.core.utils.CurrentActivityHolder
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.core.utils.*
import com.gh.gamecenter.entity.SensorsEvent
import com.gh.gamecenter.eventbus.EBDownloadStatus
import com.gh.gamecenter.eventbus.EBPackage
@ -74,7 +70,7 @@ class DefaultJsApi(
private var mFragment: Fragment? = null,
private var mBbsId: String? = "",
private var mOriginUrl: String? = "",
private val mForumName: String? = "",
private val mForumName: String? = ""
) {
companion object {
@ -94,11 +90,6 @@ class DefaultJsApi(
}
}
@JavascriptInterface
fun isEnableForceDark(msg: Any): Boolean {
return DarkModeUtils.isWebViewForceDarkEnabled
}
@JavascriptInterface
fun isGhzs(msg: Any): String {
return "true"
@ -139,7 +130,7 @@ class DefaultJsApi(
@JavascriptInterface
fun login(msg: Any) {
if (NetworkUtils.isQuickLoginEnabled(context)) {
if (SPUtils.getBoolean(Constants.SP_HAS_GET_PHONE_INFO) || NetworkUtils.isOpenMobileData(context)) {
QuickLoginHelper.startLogin(context, "浏览器")
} else {
val intent = LoginActivity.getIntent(context, "浏览器")
@ -229,7 +220,7 @@ class DefaultJsApi(
runOnUiThread {
// 若畅玩列表中安装了,优先启动畅玩游戏
if (VHelper.isInstalled(packageName)) {
VHelper.validateVSpaceBeforeAction(context, packageName, null) {
if (!VHelper.showDialogIfVSpaceIsNeeded(context, "", "", "", "")) {
VHelper.launch(context, packageName)
}
} else {
@ -256,7 +247,7 @@ class DefaultJsApi(
@JavascriptInterface
fun isInstalled(event: Any): String {
val localInstalledPackageList = PackageHelper.getInstalledPackageNameList(HaloApp.getInstance().application, 0)
val localInstalledPackageList = PackageUtils.getAllPackageName(HaloApp.getInstance().application)
val packageNameList: ArrayList<String> = event.toString().toObject() ?: ArrayList()
for (packageName in packageNameList) {
@ -338,17 +329,6 @@ class DefaultJsApi(
return HaloApp.getInstance().gid
}
@JavascriptInterface
fun getOaid(msg: Any): String {
return HaloApp.getInstance().oaid
}
@JavascriptInterface
fun getPushId(): String {
val pushProvider = ARouter.getInstance().build(RouteConsts.provider.push).navigation() as? IPushProvider
return pushProvider?.getRegistrationId(HaloApp.getInstance()) ?: "unknown"
}
@JavascriptInterface
fun showIncompatibleVersionDialog(msg: Any) {
DialogHelper.showUpgradeDialog(context)
@ -555,7 +535,7 @@ class DefaultJsApi(
@JavascriptInterface
fun getInstallStatus(event: Any): String {
val localInstalledPackageList = PackageHelper.getInstalledPackageNameList(HaloApp.getInstance().application, 0)
val localInstalledPackageList = PackageUtils.getAllPackageName(HaloApp.getInstance().application)
val packageNameList: ArrayList<String> = event.toString().toObject() ?: ArrayList()
val installStatusMap: HashMap<String, Boolean> = hashMapOf()

View File

@ -15,6 +15,7 @@ import com.gh.common.util.DirectUtils.directToLegacyVideoDetail
import com.gh.common.util.DirectUtils.directToLinkPage
import com.gh.common.util.DirectUtils.directToQa
import com.gh.common.util.PackageUtils
import com.gh.gamecenter.MainActivity
import com.gh.gamecenter.WebActivity
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.constant.EntranceConsts
@ -31,6 +32,7 @@ import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.entity.ActivityLabelEntity
import com.gh.gamecenter.entity.SubjectRecommendEntity
import com.gh.gamecenter.entity.VideoLinkEntity
import com.gh.gamecenter.eventbus.EBSkip
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.feature.utils.PlatformUtils
@ -41,6 +43,7 @@ import com.gh.gamecenter.qa.BbsType
import com.gh.gamecenter.qa.video.publish.VideoPublishActivity
import com.gh.gamecenter.subject.SubjectActivity
import com.gh.gamecenter.video.detail.VideoDetailContainerViewModel
import com.gh.gamecenter.wrapper.MainWrapperFragment
import com.lightgame.utils.Utils
import org.greenrobot.eventbus.EventBus
import java.nio.charset.Charset
@ -48,8 +51,8 @@ import java.nio.charset.Charset
object DefaultUrlHandler {
@JvmStatic
fun interceptUrl(context: Context, url: String, entrance: String, sourceEntrance: String = ""): Boolean {
return interceptUrl(context, url, null, entrance, false, sourceEntrance)
fun interceptUrl(context: Context, url: String, entrance: String): Boolean {
return interceptUrl(context, url, null, entrance, false)
}
/**
@ -63,8 +66,7 @@ object DefaultUrlHandler {
fun interceptUrl(context: Context, url: String,
traceEvent: ExposureEvent? = null,
entrance: String,
bringAppToFront: Boolean = false,
sourceEntrance: String = ""): Boolean {
bringAppToFront: Boolean = false): Boolean {
val uri = Uri.parse(url)
if ("ghzhushou" == uri.scheme) {
Utils.log("url = $url")
@ -133,7 +135,7 @@ object DefaultUrlHandler {
}
}
"question" -> DirectUtils.directToQuestionDetail(context, id, entrance, "文章链接", sourceEntrance)
"question" -> DirectUtils.directToQuestionDetail(context, id, entrance, "文章链接")
"real_name" -> DirectUtils.directToRealName(context)
@ -176,7 +178,7 @@ object DefaultUrlHandler {
if ("articles" == type) {
DirectUtils.directToCommunityArticle(
context, typeId, communityId,
entrance, "文章链接", sourceEntrance
entrance, "文章链接"
)
}
}
@ -244,22 +246,24 @@ object DefaultUrlHandler {
act,
paginationType,
fieldId,
sectionName,
sourceEntrance = sourceEntrance
sectionName
)
}
EntranceConsts.HOST_VIDEO_DETAIL -> {
DirectUtils.directToVideoDetail(context, id, entrance, path, sourceEntrance)
DirectUtils.directToVideoDetail(context, id, entrance, path)
}
EntranceConsts.HOST_VIDEO_SINGLE -> {
val referer = uri.getQueryParameter("referer") ?: ""
DirectUtils.directToVideoDetail(
context, id, VideoDetailContainerViewModel.Location.SINGLE_VIDEO.value,
false, "", entrance, "", if (TextUtils.isEmpty(referer)) "" else referer, sourceEntrance
false, "", entrance, "", if (TextUtils.isEmpty(referer)) "" else referer
)
}
EntranceConsts.HOST_VIDEO_STREAMING_HOME -> {
DirectUtils.directToHomeVideoTab(context)
intent = Intent(context, MainActivity::class.java)
intent.flags = Intent.FLAG_ACTIVITY_CLEAR_TOP
intent.putExtra(MainActivity.SWITCH_TO_VIDEO, true)
context.startActivity(intent)
}
EntranceConsts.HOST_VIDEO_STREAMING_DESC -> {
directToGameDetailVideoStreaming(context, id, entrance)
@ -268,6 +272,10 @@ object DefaultUrlHandler {
directToGameVideo(context, id, entrance, "")
}
EntranceConsts.HOST_CATEGORY -> {
val title = uri.getQueryParameter("title")
DirectUtils.directCategoryDirectory(context, id, title ?: "", entrance, "")
}
EntranceConsts.HOST_COLUMN_COLLECTION -> {
val name = uri.getQueryParameter("name")
DirectUtils.directToColumnCollection(context, id, -1, entrance, name ?: "")
@ -317,7 +325,7 @@ object DefaultUrlHandler {
val linkData = Base64.decode(dataString, Base64.DEFAULT)
val linkDataString = String(linkData, Charset.defaultCharset())
val le = gson.fromJson(linkDataString, LinkEntity::class.java)
directToLinkPage(context, le, entrance, sourceEntrance, "")
directToLinkPage(context, le, entrance, "")
}
} catch (e: Exception) {
e.printStackTrace()
@ -356,8 +364,9 @@ object DefaultUrlHandler {
}
EntranceConsts.HOST_FORUM -> {
val position = uri.getQueryParameter(EntranceConsts.KEY_POSITION)?.toInt()
DirectUtils.directToHomeCommunityTab(context)
DirectUtils.directToForum(context, position ?: 0)
}
EntranceConsts.HOST_UPLOAD_VIDEO_NEW -> {
@ -374,7 +383,7 @@ object DefaultUrlHandler {
val iconSubscript = uri.getQueryParameter("game_icon_subscript") ?: ""
val gameEntity =
if (forumType == BbsType.OFFICIAL_BBS.value && gameId.isNotEmpty() && gameName.isNotEmpty() && icon.isNotEmpty()) {
GameEntity(_id = gameId, mName = gameName, mIcon = icon, mIconSubscript = iconSubscript)
GameEntity(id = gameId, mName = gameName, mIcon = icon, mIconSubscript = iconSubscript)
} else null
val activityLabelEntity = if (activityId.isNotEmpty() && activityName.isNotEmpty()) {
ActivityLabelEntity(
@ -494,11 +503,13 @@ object DefaultUrlHandler {
EntranceConsts.HOST_GAME_LIBRARY -> {
DirectUtils.directToMainActivity(context)
EventBus.getDefault().post(EBSkip(MainActivity.EB_SKIP_MAIN, MainWrapperFragment.TYPE_GAME_LIBRARY))
}
EntranceConsts.HOST_HOME_GAME_COLLECTION_SQUARE -> {
DirectUtils.directToMainActivity(context)
DirectUtils.directToHomeDefaultTab(context)
EventBus.getDefault()
.post(EBSkip(MainActivity.EB_SKIP_MAIN, MainWrapperFragment.TYPE_HOME))
EventBus.getDefault().post(EBReuse(host))
}
@ -553,7 +564,7 @@ object DefaultUrlHandler {
}
// 处理内部页面逻辑
if (transformNormalScheme(context, url, entrance, sourceEntrance)) {
if (transformNormalScheme(context, url, entrance)) {
return true
}
@ -562,14 +573,14 @@ object DefaultUrlHandler {
}
@JvmStatic
fun transformNormalScheme(context: Context, url: String, entrance: String, sourceEntrance: String): Boolean {
val b = transformNewNormalScheme(context, url, entrance, sourceEntrance)
fun transformNormalScheme(context: Context, url: String, entrance: String): Boolean {
val b = transformNewNormalScheme(context, url, entrance)
if (b) return b
return transformOldNormalScheme(context, url, entrance, sourceEntrance)
return transformOldNormalScheme(context, url, entrance)
}
@JvmStatic
fun transformOldNormalScheme(context: Context, url: String, entrance: String, sourceEntrance: String): Boolean {
fun transformOldNormalScheme(context: Context, url: String, entrance: String): Boolean {
val uri = Uri.parse(url)
if (uri.host == "www.ghzs666.com"
|| uri.host == "www.ghzs.com"
@ -585,7 +596,6 @@ object DefaultUrlHandler {
DirectUtils.directToGameDetail(
context,
gameId,
"",
entrance,
autoDownload = false,
traceEvent = null
@ -595,7 +605,7 @@ object DefaultUrlHandler {
val questionId = split("/")[2]
val answerId = uri.getQueryParameter("answer")
if (answerId.isNullOrEmpty()) {
DirectUtils.directToQuestionDetail(context, questionId, entrance, "", sourceEntrance)
DirectUtils.directToQuestionDetail(context, questionId, entrance, "")
} else {
DirectUtils.directToAnswerDetail(context, answerId, entrance, "")
}
@ -625,7 +635,7 @@ object DefaultUrlHandler {
if ("articles" == type || "article" == type) {
DirectUtils.directToCommunityArticle(
context, typeId, communityId,
entrance, "文章链接", sourceEntrance
entrance, "文章链接"
)
}
}
@ -656,7 +666,7 @@ object DefaultUrlHandler {
}
@JvmStatic
fun transformNewNormalScheme(context: Context, url: String, entrance: String, sourceEntrance: String): Boolean {
fun transformNewNormalScheme(context: Context, url: String, entrance: String): Boolean {
val uri = Uri.parse(url)
if (uri.host == "www.ghzs666.com"
|| uri.host == "www.ghzs.com"
@ -674,7 +684,7 @@ object DefaultUrlHandler {
val articleId = splits[2].substring(7)
DirectUtils.directToCommunityArticle(
context, articleId, "",
entrance, "文章链接", sourceEntrance
entrance, "文章链接"
)
}
//https://m.ghzs666.com/article/文章ID
@ -694,7 +704,7 @@ object DefaultUrlHandler {
//https://m.ghzs666.com/bbs/video-视频ID
splits.size >= 3 && splits[1] == "bbs" && splits[2].startsWith("video-") -> {
val videoId = splits[2].substring(6)
DirectUtils.directToVideoDetail(context, videoId, entrance, sourceEntrance)
DirectUtils.directToVideoDetail(context, videoId, entrance)
}
else -> return false
}

View File

@ -2,16 +2,17 @@ package com.gh.common
import com.gh.common.exposure.ExposureManager
import com.gh.common.filter.RegionSettingHelper
import com.gh.common.util.AdHelper
import com.gh.common.videolog.VideoRecordUtils
import com.gh.download.DownloadDataHelper
import com.gh.gamecenter.common.loghub.LoghubUtils
import com.gh.gamecenter.common.retrofit.Response
import com.gh.gamecenter.common.utils.doOnMainProcessOnly
import com.gh.gamecenter.common.utils.tryCatchInRelease
import com.gh.gamecenter.core.runOnUiThread
import com.gh.gamecenter.entity.TimeEntity
import com.gh.gamecenter.retrofit.RetrofitManager
import com.halo.assistant.HaloApp
import com.lightgame.utils.Utils
import io.reactivex.schedulers.Schedulers
import kotlin.concurrent.fixedRateTimer
@ -25,6 +26,7 @@ object FixedRateJobHelper {
private const val DOWNLOAD_HEARTBEAT_PERIOD: Long = 60 * 1000L
private const val DOWNLOAD_HEARTBEAT_SHEET_PERIOD: Long = 15 * 1000L
private const val STARTUP_AD: Long = 30 * 60 * 1000L
private var mExecuteCount: Int = 0
@ -32,56 +34,58 @@ object FixedRateJobHelper {
@JvmStatic
fun begin() {
// 时间检查每15秒检查一次
fixedRateTimer("Global-Fixed-Rate-Timer", initialDelay = 100, period = CHECKER_PERIOD) {
val elapsedTime = mExecuteCount * CHECKER_PERIOD
// 时间校对10分钟一次
if (elapsedTime % TIME_PERIOD == 0L) {
RetrofitManager.getInstance().api.time
.subscribeOn(Schedulers.io())
.subscribe(object : Response<TimeEntity>() {
override fun onResponse(response: TimeEntity?) {
val serverTime = response?.time
serverTime?.let {
timeDeltaBetweenServerAndClient = it * 1000 - System.currentTimeMillis()
doOnMainProcessOnly {
// 时间检查每15秒检查一次
fixedRateTimer("Global-Fixed-Rate-Timer", initialDelay = 100, period = CHECKER_PERIOD) {
val elapsedTime = mExecuteCount * CHECKER_PERIOD
// 时间校对10分钟一次
if (elapsedTime % TIME_PERIOD == 0L) {
RetrofitManager.getInstance().api.time
.subscribeOn(Schedulers.io())
.subscribe(object : Response<TimeEntity>() {
override fun onResponse(response: TimeEntity?) {
val serverTime = response?.time
serverTime?.let {
timeDeltaBetweenServerAndClient = it * 1000 - System.currentTimeMillis()
}
}
}
})
}
// 提交曝光数据
if (elapsedTime % EXPOSURE_PERIOD == 0L) {
ExposureManager.commitSavedExposureEvents(true)
}
// 分片检测下载进度
if (elapsedTime % DOWNLOAD_HEARTBEAT_SHEET_PERIOD == 0L) {
tryCatchInRelease {
val upload = (mExecuteCount * CHECKER_PERIOD) % DOWNLOAD_HEARTBEAT_PERIOD == 0L
DownloadDataHelper.uploadDownloadHeartbeat(upload)
})
}
}
// 提交普通 loghub 数据
if (elapsedTime % LOGHUB_PERIOD == 0L) {
runOnUiThread {
LoghubUtils.commitSavedLoghubEvents(true)
// 提交曝光数据
if (elapsedTime % EXPOSURE_PERIOD == 0L) {
ExposureManager.commitSavedExposureEvents(true)
}
}
// 更新游戏屏蔽信息
if (elapsedTime % REGION_SETTING_PERIOD == 0L) {
if (HaloApp.getInstance().isRunningForeground) {
RegionSettingHelper.getRegionSetting()
// 分片检测下载进度
if (elapsedTime % DOWNLOAD_HEARTBEAT_SHEET_PERIOD == 0L) {
tryCatchInRelease {
val upload = (mExecuteCount * CHECKER_PERIOD) % DOWNLOAD_HEARTBEAT_PERIOD == 0L
DownloadDataHelper.uploadDownloadHeartbeat(upload)
}
}
}
// 提交视频浏览记录数据
if (elapsedTime % VIDEO_RECORD_PERIOD == 0L) {
VideoRecordUtils.commitVideoRecord()
}
// 提交普通 loghub 数据
if (elapsedTime % LOGHUB_PERIOD == 0L) {
runOnUiThread {
LoghubUtils.commitSavedLoghubEvents(true)
}
}
mExecuteCount++
// 更新游戏屏蔽信息
if (elapsedTime % REGION_SETTING_PERIOD == 0L) {
if (HaloApp.getInstance().isRunningForeground) {
RegionSettingHelper.getRegionSetting()
}
}
// 提交视频浏览记录数据
if (elapsedTime % VIDEO_RECORD_PERIOD == 0L) {
VideoRecordUtils.commitVideoRecord()
}
mExecuteCount++
}
}
}
}

View File

@ -1,351 +0,0 @@
package com.gh.common.browse
import android.os.Handler
import android.os.Looper
import android.os.Message
import androidx.lifecycle.*
import androidx.lifecycle.Lifecycle.Event
/**
* 浏览时长计时器核心接口类,用于页面浏览时长相关埋点上报
*/
interface IBrowseTimerCore {
/**
* 开始计时
*/
fun start()
/**
* 结束计时
*/
fun stop()
}
/**
* 浏览时长计时器核心实现类
*/
class BrowseTimerCore internal constructor() : IBrowseTimerCore {
/**
* 延迟执行的时间
*/
var delayInMills: Long = 3000L
/**
* 开始计时函数回调
*/
var onStart: (() -> Unit)? = null
/**
* 结束计时函数回调
*/
var onResult: ((Long) -> Unit)? = null
/**
* 开始计时的时间点
*/
private var startTimeInMills: Long = 0L
/**
* Handler操作类
*/
private val handler = object : Handler(Looper.getMainLooper()) {
override fun handleMessage(msg: Message) {
if (msg.what == MESSAGE_START) {
dispatchOnStart()
}
}
}
/**
* 延迟执行开始计时
* @see delayInMills
* @see onStart
*/
override fun start() {
if (delayInMills <= 0) {
dispatchOnStart()
} else {
handler.sendEmptyMessageDelayed(MESSAGE_START, delayInMills)
}
}
/**
* 结束计时,统计浏览时长并回调结束计时函数
* @see onResult
*/
override fun stop() {
handler.removeMessages(MESSAGE_START)
if (startTimeInMills > 0L) {
onResult?.invoke(System.currentTimeMillis() - startTimeInMills)
startTimeInMills = 0L
}
}
/**
* 开始计时,回调开始计时函数
*/
private fun dispatchOnStart() {
startTimeInMills = System.currentTimeMillis()
onStart?.invoke()
}
companion object {
private const val MESSAGE_START = 1
}
}
/**
* 无数据浏览计时器接口类
*/
interface IBrowseTimer : IBrowseTimerCore {
fun withDelayInMills(delayInMills: Long): IBrowseTimer
fun withStart(onStart: () -> Unit): IBrowseTimer
fun withResult(onResult: (Long) -> Unit): IBrowseTimer
}
/**
* 无数据的浏览计时器实现类
*/
class BrowseTimer : IBrowseTimer {
private val core = BrowseTimerCore()
private var isStarted: Boolean = false
override fun withDelayInMills(delayInMills: Long): IBrowseTimer {
core.delayInMills = delayInMills
return this
}
override fun withStart(onStart: () -> Unit): IBrowseTimer {
core.onStart = onStart
return this
}
override fun withResult(onResult: (Long) -> Unit): IBrowseTimer {
core.onResult = onResult
return this
}
override fun start() {
if (isStarted) return
isStarted = true
core.start()
}
override fun stop() {
if (!isStarted) return
core.stop()
isStarted = false
}
}
/**
* 支持Lifecycle的无数据的浏览计时器
*/
class LifecycleBoundBrowseTimer internal constructor(
private val base: IBrowseTimer,
private val onStateChanged: (IBrowseTimer, Event) -> Unit
) : IBrowseTimer, LifecycleEventObserver {
override fun withDelayInMills(delayInMills: Long): IBrowseTimer {
return base.withDelayInMills(delayInMills)
}
override fun withStart(onStart: () -> Unit): IBrowseTimer {
return base.withStart(onStart)
}
override fun withResult(onResult: (Long) -> Unit): IBrowseTimer {
return base.withResult(onResult)
}
override fun start() {
base.start()
}
override fun stop() {
base.stop()
}
override fun onStateChanged(source: LifecycleOwner, event: Event) {
onStateChanged.invoke(this, event)
}
}
fun IBrowseTimer.withLifecycle(
owner: LifecycleOwner,
onStateChanged: (IBrowseTimer, Event) -> Unit = { timer, event ->
when(event) {
Event.ON_START -> timer.start()
Event.ON_STOP -> timer.stop()
else -> {}
}
}
): LifecycleBoundBrowseTimer = LifecycleBoundBrowseTimer(this, onStateChanged).apply {
owner.lifecycle.addObserver(this)
}
/**
* 带数据的浏览计时器接口类
*/
interface IValueBrowseTimer<T> : IBrowseTimerCore {
fun withDelayInMills(delayInMills: Long): IValueBrowseTimer<T>
fun withStart(onStart: (T?) -> Unit): IValueBrowseTimer<T>
fun withResult(onResult: (T?, Long) -> Unit): IValueBrowseTimer<T>
fun dispatchValue(value: T?)
}
/**
* 带数据的浏览计时器实现类
*/
class ValueBrowseTimer<T> : IValueBrowseTimer<T> {
private val core = BrowseTimerCore()
private var isDispatchValue: Boolean = false
private var isStarted: Boolean = false
private var value: T? = null
override fun withDelayInMills(delayInMills: Long): IValueBrowseTimer<T> {
core.delayInMills = delayInMills
return this
}
override fun withStart(onStart: (T?) -> Unit): IValueBrowseTimer<T> {
core.onStart = { onStart.invoke(value) }
return this
}
override fun withResult(onResult: (T?, Long) -> Unit): IValueBrowseTimer<T> {
core.onResult = { onResult.invoke(value, it) }
return this
}
override fun start() {
if (isStarted) return
isStarted = true
if (isDispatchValue) {
core.start()
}
}
override fun stop() {
if (!isStarted) return
core.stop()
isStarted = false
}
override fun dispatchValue(value: T?) {
this.value = value
if (isStarted && !isDispatchValue) {
core.start()
}
isDispatchValue = true
}
}
/**
* 支持LiveData的带数据的浏览计时器
*/
class ObserverBoundValueBrowseTimer<T> internal constructor(private val base: IValueBrowseTimer<T>) : IValueBrowseTimer<T>, Observer<T> {
override fun withDelayInMills(delayInMills: Long): IValueBrowseTimer<T> {
return base.withDelayInMills(delayInMills)
}
override fun withResult(onResult: (T?, Long) -> Unit): IValueBrowseTimer<T> {
return base.withResult(onResult)
}
override fun withStart(onStart: (T?) -> Unit): IValueBrowseTimer<T> {
return base.withStart(onStart)
}
override fun start() {
base.start()
}
override fun stop() {
base.stop()
}
override fun dispatchValue(value: T?) {
base.dispatchValue(value)
}
override fun onChanged(t: T) {
dispatchValue(t)
}
}
/**
* 支持Lifecycle的带数据的浏览计时器
*/
class LifecycleBoundValueBrowseTimer<T> internal constructor(
private val base: IValueBrowseTimer<T>,
private val onStateChanged: (IValueBrowseTimer<T>, Event) -> Unit
) : IValueBrowseTimer<T>, LifecycleEventObserver {
override fun withDelayInMills(delayInMills: Long): IValueBrowseTimer<T> {
return base.withDelayInMills(delayInMills)
}
override fun withResult(onResult: (T?, Long) -> Unit): IValueBrowseTimer<T> {
return base.withResult(onResult)
}
override fun withStart(onStart: (T?) -> Unit): IValueBrowseTimer<T> {
return base.withStart(onStart)
}
override fun start() {
base.start()
}
override fun stop() {
base.stop()
}
override fun dispatchValue(value: T?) {
base.dispatchValue(value)
}
override fun onStateChanged(source: LifecycleOwner, event: Event) {
onStateChanged.invoke(this, event)
}
}
fun <T> IValueBrowseTimer<T>.asObserver(): ObserverBoundValueBrowseTimer<T> = ObserverBoundValueBrowseTimer(this)
fun <T> IValueBrowseTimer<T>.withLifecycle(
owner: LifecycleOwner,
onStateChanged: (IValueBrowseTimer<T>, Event) -> Unit = { timer, event ->
when(event) {
Event.ON_START -> timer.start()
Event.ON_STOP -> timer.stop()
else -> {}
}
}
): LifecycleBoundValueBrowseTimer<T> = LifecycleBoundValueBrowseTimer(this, onStateChanged).apply {
owner.lifecycle.addObserver(this)
}

View File

@ -6,8 +6,8 @@ class DownloadChainBuilder {
private var processEndCallback: ((asVGame: Boolean, Any?) -> Unit)? = null
fun setProcessEndCallback(gameId: String, callback: (asVGame: Boolean, Any?) -> Unit): DownloadChainBuilder {
processEndCallback = VaPluginDownloadWrapper(gameId = gameId, callback = callback) // 其他需要添加行为的装饰者可以一直包装A(B(C(callback))), 执行顺序 A->B->C->callback
fun setProcessEndCallback(callback: (asVGame: Boolean, Any?) -> Unit): DownloadChainBuilder {
processEndCallback = callback
return this
}

View File

@ -1,6 +1,5 @@
package com.gh.common.chain
import android.app.Activity
import android.content.Context
import com.gh.common.util.DialogUtils
import com.gh.common.util.DirectUtils
@ -12,21 +11,8 @@ class LandPageAddressHandler : DownloadChainHandler() {
override fun handleRequest(context: Context, gameEntity: GameEntity, asVGame: Boolean) {
if (gameEntity.isLandPageAddressDialog()) {
TempCertificationUtils.checkCertificationBeforeAction(gameEntity) {
if (context is Activity && context.isFinishing) {
// 当前 context 已经无效,不需要再传递执行下去了
return@checkCertificationBeforeAction
}
DialogUtils.showLandPageAddressDialog(context, gameEntity) {// 跳转第三方落地页
if (gameEntity.isLandPageAddressDialogShowOnly()) {
if (hasNext()) {
getNext()?.handleRequest(context, gameEntity, asVGame)
} else {
processEndCallback?.invoke(asVGame, null)
}
} else {
DirectUtils.directToExternalBrowser(context, gameEntity.landPageAddressDialog!!.link!!)
}
DirectUtils.directToExternalBrowser(context, gameEntity.landPageAddressDialog!!.link!!)
}
}
} else {

View File

@ -1,6 +1,5 @@
package com.gh.common.chain
import android.app.Activity
import android.content.Context
import com.gh.common.util.DialogUtils
import com.gh.common.util.TempCertificationUtils
@ -11,11 +10,6 @@ class OverseaDownloadHandler : DownloadChainHandler() {
override fun handleRequest(context: Context, gameEntity: GameEntity, asVGame: Boolean) {
if (gameEntity.isOverseaAddressDialog()) {
TempCertificationUtils.checkCertificationBeforeAction(gameEntity) {
if (context is Activity && context.isFinishing) {
// 当前 context 已经无效,不需要再传递执行下去了
return@checkCertificationBeforeAction
}
DialogUtils.showOverseaDownloadDialog(context, gameEntity) {// 跳转海外下载地址弹窗
if (hasNext()) {
getNext()?.handleRequest(context, gameEntity, asVGame)

View File

@ -1,12 +0,0 @@
package com.gh.common.chain
import com.gh.vspace.VHelper
class VaPluginDownloadWrapper(val gameId: String, val callback: (Boolean, Any?) -> Unit) : (Boolean, Any?) -> Unit {
override fun invoke(asVGame: Boolean, any: Any?) {
callback.invoke(asVGame, any)
if (asVGame) {
VHelper.initVaPlugin(gameId)
}
}
}

View File

@ -16,7 +16,7 @@ class ValidateVSpaceHandler : DownloadChainHandler() {
}
if (asVGame) {
VHelper.validateVSpaceBeforeAction(context,gameEntity.getUniquePackageName(), gameEntity) {
VHelper.validateVSpaceBeforeAction(context, gameEntity) {
closure.invoke()
}
} else {

View File

@ -30,7 +30,7 @@ class VersionNumberHandler : DownloadChainHandler() {
"温馨提示",
gameEntity.getVersionNumberString(),
"继续下载",
com.gh.gamecenter.common.R.string.cancel.toResString(),
R.string.cancel.toResString(),
{
confirmCallback.invoke()
SensorsBridge.trackGameDemoDialogClick(
@ -42,7 +42,7 @@ class VersionNumberHandler : DownloadChainHandler() {
},
cancelClickCallback = {
SensorsBridge.trackGameDemoDialogClick(
buttonName = com.gh.gamecenter.common.R.string.cancel.toResString(),
buttonName = R.string.cancel.toResString(),
gameId = gameEntity.id,
gameName = gameEntity.name ?: "",
gameType = gameEntity.categoryChinese

View File

@ -1,13 +1,11 @@
package com.gh.common.constant;
import android.annotation.SuppressLint;
import android.content.IntentFilter;
import android.content.SharedPreferences;
import android.os.Build;
import android.preference.PreferenceManager;
import android.text.TextUtils;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import com.gh.common.util.PackageHelper;
@ -16,28 +14,21 @@ import com.gh.gamecenter.BuildConfig;
import com.gh.gamecenter.common.constant.CommonConsts;
import com.gh.gamecenter.common.constant.Constants;
import com.gh.gamecenter.common.eventbus.EBReuse;
import com.gh.gamecenter.common.exposure.meta.MetaUtil;
import com.gh.gamecenter.common.retrofit.BiResponse;
import com.gh.gamecenter.common.retrofit.Response;
import com.gh.gamecenter.common.utils.DarkModeUtils;
import com.gh.gamecenter.common.utils.EnvHelper;
import com.gh.gamecenter.core.AppExecutor;
import com.gh.gamecenter.core.utils.GsonUtils;
import com.gh.gamecenter.core.utils.SPUtils;
import com.gh.gamecenter.core.utils.UrlFilterUtils;
import com.gh.gamecenter.entity.AppEntity;
import com.gh.gamecenter.entity.FloatWindowSettingEntity;
import com.gh.gamecenter.entity.GameGuidePopupEntity;
import com.gh.gamecenter.entity.NewApiSettingsEntity;
import com.gh.gamecenter.entity.NewSettingsEntity;
import com.gh.gamecenter.entity.VNewSetting;
import com.gh.gamecenter.entity.VSetting;
import com.gh.gamecenter.feature.entity.SettingsEntity;
import com.gh.gamecenter.feature.entity.SimulatorEntity;
import com.gh.gamecenter.feature.utils.ContentBlockedHelper;
import com.gh.gamecenter.receiver.PackageChangeBroadcastReceiver;
import com.gh.gamecenter.retrofit.RetrofitManager;
import com.gh.gamecenter.retrofit.service.VApiService;
import com.gh.vspace.VHelper;
import com.halo.assistant.HaloApp;
@ -48,12 +39,8 @@ import org.json.JSONObject;
import java.io.IOException;
import java.util.Locale;
import io.reactivex.Observable;
import io.reactivex.Single;
import io.reactivex.SingleSource;
import io.reactivex.functions.Function;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;
import io.reactivex.subjects.BehaviorSubject;
import okhttp3.ResponseBody;
public class Config {
@ -63,9 +50,6 @@ public class Config {
public static final String NEW_API_HOST = EnvHelper.getNewHost();
public static final String VAPI_HOST = EnvHelper.getVHost();
public static final String WGAME_CPM_BUSIAPPID = BuildConfig.WGAME_CPM_BUSIAPPID;
public static final String WGAME_CPM_API_HOST = EnvHelper.getWGameCPMHost();
// Third-Party confs
public static final String WECHAT_APPID = BuildConfig.WECHAT_APPID;
public static final String WECHAT_SECRET = BuildConfig.WECHAT_SECRET;
@ -73,7 +57,8 @@ public class Config {
public static final String WEIBO_APPKEY = BuildConfig.WEIBO_APPKEY;
public static final String QUICK_LOGIN_APPID = BuildConfig.QUICK_LOGIN_APPID;
public static final String QUICK_LOGIN_APPKEY = BuildConfig.QUICK_LOGIN_APPKEY;
public static final String URL_ARTICLE = "www.ghzs666.com/article/"; // ghzs/ghzs666 统一
// http://www.ghzs666.com/article/${articleId}.html
public static final String URL_ARTICLE = "http://www.ghzs666.com/article/"; // ghzs/ghzs666 统一
private static final String SETTINGS_KEY = "settingsKey";
@ -84,12 +69,6 @@ public class Config {
private static NewApiSettingsEntity.NightMode mNightModeSetting;
private static SimulatorEntity mNewSimulatorEntity;
private static VSetting mVSetting;
private volatile static VNewSetting mVNewSetting;
private static FloatWindowSettingEntity mFloatWindowSetting;
private static AppEntity mNew32UpdateEntity;
private static BehaviorSubject<VNewSetting> vNewSettingSubject = BehaviorSubject.create();
private static GameGuidePopupEntity mGameGuidePopupEntity;
private static SharedPreferences mDefaultSharedPreferences;
@ -99,11 +78,25 @@ public class Config {
return !SPUtils.getBoolean(Constants.SP_TEENAGER_MODE);
}
/**
* VPN 开关选项是否开启
*/
public static boolean isVpnOptionEnabled() {
if (mNewApiSettingsEntity == null
|| mNewApiSettingsEntity.getInstall() == null
|| mNewApiSettingsEntity.getInstall().getVpnRequired() == null) {
return false;
}
return mNewApiSettingsEntity.getInstall().getVpnRequired().getShouldShowVpnOption();
}
public static void setSettings(SettingsEntity settingsEntity) {
getPreferences().edit().putString(SETTINGS_KEY, GsonUtils.toJson(settingsEntity)).apply();
mSettingsEntity = settingsEntity;
PackageHelper.refreshPackageNameList();
// 加载完设置后刷新下
PackageHelper.initList();
}
@Nullable
@ -204,52 +197,6 @@ public class Config {
return mVSetting;
}
@Nullable
public static VNewSetting getVNewSettingEntity() {
if (mVNewSetting == null) {
try {
String json = SPUtils.getString(Constants.SP_V_NEW_SETTINGS);
if (!TextUtils.isEmpty(json)) {
mVNewSetting = GsonUtils.fromJson(json, VNewSetting.class);
vNewSettingSubject.onNext(mVNewSetting);
}
} catch (Exception e) {
e.printStackTrace();
}
}
return mVNewSetting;
}
@Nullable
public static FloatWindowSettingEntity getFloatWindowSettingEntity() {
if (mFloatWindowSetting == null) {
try {
String json = SPUtils.getString(Constants.SP_FLOAT_WINDOW_SETTINGS);
if (!TextUtils.isEmpty(json)) {
mFloatWindowSetting = GsonUtils.fromJson(json, FloatWindowSettingEntity.class);
}
} catch (Exception e) {
e.printStackTrace();
}
}
return mFloatWindowSetting;
}
@NonNull
public static Observable<VNewSetting> getVNewSettingObservable() {
if (mVNewSetting != null) {
return Observable.just(mVNewSetting);
} else {
return vNewSettingSubject.hide();
}
}
@Nullable
public static AppEntity getNew32UpdateEntity() {
return mNew32UpdateEntity;
}
/**
* 请求网络数据,尝试刷新畅玩相关配置
*/
@ -258,6 +205,7 @@ public class Config {
RetrofitManager.getInstance()
.getVApi().getSettings(BuildConfig.VERSION_NAME, Build.VERSION.SDK_INT)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new BiResponse<VSetting>() {
@Override
public void onSuccess(VSetting data) {
@ -269,35 +217,6 @@ public class Config {
});
}
@SuppressLint("CheckResult")
public static void getNewSetting() {
VApiService vApi = RetrofitManager.getInstance().getVApi();
vApi.getNewSettings(BuildConfig.VERSION_NAME, Build.VERSION.SDK_INT).flatMap(new Function<VNewSetting, SingleSource<AppEntity>>() {
@Override
public SingleSource<AppEntity> apply(VNewSetting data) throws Exception {
mVNewSetting = data;
vNewSettingSubject.onNext(mVNewSetting);
SPUtils.setString(Constants.SP_V_NEW_SETTINGS, GsonUtils.toJson(data));
if (data.getVa() != null && data.getVa().getArch32() != null) {
String versionNameByPackageName = PackageUtils.getVersionNameByPackageName(data.getVa().getArch32().getPackageName());
return vApi.getNewPackageUpdate(
BuildConfig.VERSION_NAME,
versionNameByPackageName != null ? versionNameByPackageName : "",
HaloApp.getInstance().getChannel()
);
}
return Single.error(new IllegalStateException("VNewSetting entity is not expected"));
}
})
.subscribeOn(Schedulers.io())
.subscribe(new BiResponse<AppEntity>() {
@Override
public void onSuccess(AppEntity data) {
mNew32UpdateEntity = data;
}
});
}
@Nullable
public static GameGuidePopupEntity getGameGuidePopupEntity() {
return mGameGuidePopupEntity;
@ -321,6 +240,7 @@ public class Config {
RetrofitManager.getInstance()
.getApi().getSettings(PackageUtils.getGhVersionName(), channel)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new Response<SettingsEntity>() {
@Override
public void onResponse(SettingsEntity response) {
@ -333,7 +253,7 @@ public class Config {
edit.apply();
if (!SPUtils.getBoolean(Constants.SP_TEENAGER_MODE)) {
AppExecutor.getUiExecutor().execute(() -> EventBus.getDefault().post(new EBReuse("Refresh")));
EventBus.getDefault().post(new EBReuse("Refresh"));
}
}
});
@ -341,6 +261,7 @@ public class Config {
RetrofitManager.getInstance()
.getApi().getNewSettings(Build.MANUFACTURER, Build.MODEL, channel, Build.VERSION.SDK_INT, BuildConfig.VERSION_NAME)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new BiResponse<NewSettingsEntity>() {
@Override
public void onSuccess(NewSettingsEntity data) {
@ -350,12 +271,11 @@ public class Config {
});
refreshVSettingEntity();
getNewSetting();
getFloatWindowSetting();
RetrofitManager.getInstance()
.getApi().getGameGuidePopup(Build.MANUFACTURER, Build.VERSION.RELEASE, Build.MODEL, channel, BuildConfig.VERSION_NAME)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new BiResponse<GameGuidePopupEntity>() {
@Override
public void onSuccess(GameGuidePopupEntity data) {
@ -367,6 +287,7 @@ public class Config {
if (manufacturer.equals("OPPO") || manufacturer.equals("VIVO")) {
RetrofitManager.getInstance().getNewApi().getBrowserHintUrl(manufacturer)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new BiResponse<ResponseBody>() {
@Override
public void onSuccess(ResponseBody data) {
@ -390,13 +311,12 @@ public class Config {
String filterString = UrlFilterUtils.getFilterQuery(
"manufacturer", Build.MANUFACTURER,
"model", Build.MODEL,
"android_sdk_version", String.valueOf(Build.VERSION.SDK_INT),
"rom", MetaUtil.INSTANCE.getRom().name() + " " + MetaUtil.INSTANCE.getRom().getVersionName()
);
"android_sdk_version", String.valueOf(Build.VERSION.SDK_INT));
RetrofitManager.getInstance()
.getNewApi().getNewSettings(PackageUtils.getGhVersionName(), channel, filterString)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(new BiResponse<NewApiSettingsEntity>() {
@Override
public void onSuccess(NewApiSettingsEntity data) {
@ -405,7 +325,7 @@ public class Config {
mNewSimulatorEntity = data.getSimulator();
if (HaloApp.getInstance().isNewForThisVersion && mNightModeSetting != null && mNightModeSetting.getInstall()) {
DarkModeUtils.INSTANCE.updateFollowSystemDarkModeToSp(true);
AppExecutor.getUiExecutor().execute(DarkModeUtils.INSTANCE::initDarkMode);
DarkModeUtils.INSTANCE.initDarkMode();
}
SPUtils.setString(Constants.SP_NEW_API_SETTINGS, GsonUtils.toJson(data));
@ -413,45 +333,8 @@ public class Config {
if (mNewApiSettingsEntity.getGameShieldContents() != null) {
ContentBlockedHelper.INSTANCE.init(mNewApiSettingsEntity.getGameShieldContents());
}
// 更新安装列表是否开启的配置
if (mNewApiSettingsEntity.getInstalledComplianceSwitch() != null) {
PackageHelper.INSTANCE.updateIsGetInstalledPackagesApiAgreedRequired(mNewApiSettingsEntity.getInstalledComplianceSwitch());
} else {
PackageHelper.INSTANCE.updateIsGetInstalledPackagesApiAgreedRequired(false);
}
// 更新包名监听是否开启
if (mNewApiSettingsEntity.isPackageObserveEnable()) {
AppExecutor.getUiExecutor().execute(() -> observePackageChange(mNewApiSettingsEntity.getPackageObserveActions()));
}
}
});
}
}
@SuppressLint("CheckResult")
private static void getFloatWindowSetting() {
RetrofitManager.getInstance().getNewApi()
.getFloatWindowSettings()
.subscribeOn(Schedulers.io())
.subscribe(new BiResponse<FloatWindowSettingEntity>() {
@Override
public void onSuccess(FloatWindowSettingEntity data) {
mFloatWindowSetting = data;
SPUtils.setString(Constants.SP_FLOAT_WINDOW_SETTINGS, GsonUtils.toJson(data));
}
});
}
public static void observePackageChange(NewApiSettingsEntity.PackageObserveActions packageObserveActions) {
PackageChangeBroadcastReceiver receiver = new PackageChangeBroadcastReceiver(packageObserveActions);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(packageObserveActions.getAdd());
intentFilter.addAction(packageObserveActions.getRem());
intentFilter.addAction(packageObserveActions.getRep());
intentFilter.addDataScheme("package");
HaloApp.getInstance().registerReceiver(receiver, intentFilter);
}
}

View File

@ -120,14 +120,14 @@ object AddKaiFuBindingAdapter {
@BindingAdapter("kaiFuTextColor", "kaiFuTextPosition")
fun kaiFuTextColor(view: EditText, dataMark: Int, position: Int) {
if (dataMark == 1 && view.id == R.id.kaifu_add_time || dataMark == 2 && view.id == R.id.kaifu_add_first_name || dataMark == 3 && view.id == R.id.kaifu_add_server_name || dataMark == 4) {
view.setTextColor(ContextCompat.getColor(view.context, com.gh.gamecenter.common.R.color.secondary_red))
view.setHintTextColor(ContextCompat.getColor(view.context, com.gh.gamecenter.common.R.color.secondary_red))
view.setTextColor(ContextCompat.getColor(view.context, R.color.secondary_red))
view.setHintTextColor(ContextCompat.getColor(view.context, R.color.secondary_red))
} else if (position == 0) {
view.setTextColor(ContextCompat.getColor(view.context, com.gh.gamecenter.common.R.color.hint))
view.setHintTextColor(ContextCompat.getColor(view.context, com.gh.gamecenter.common.R.color.hint))
view.setTextColor(ContextCompat.getColor(view.context, R.color.hint))
view.setHintTextColor(ContextCompat.getColor(view.context, R.color.hint))
} else {
view.setTextColor(ContextCompat.getColor(view.context, com.gh.gamecenter.common.R.color.text_primary))
view.setHintTextColor(ContextCompat.getColor(view.context, com.gh.gamecenter.common.R.color.hint))
view.setTextColor(ContextCompat.getColor(view.context, R.color.text_primary))
view.setHintTextColor(ContextCompat.getColor(view.context, R.color.hint))
}
}
@ -176,7 +176,7 @@ object AddKaiFuBindingAdapter {
popupWindow.isTouchable = true
popupWindow.inputMethodMode = PopupWindow.INPUT_METHOD_NEEDED
popupWindow.isOutsideTouchable = true
popupWindow.animationStyle = com.gh.gamecenter.common.R.style.popwindow_option_anim_style
popupWindow.animationStyle = R.style.popwindow_option_anim_style
// 设置偏移
windowPos[1] = windowPos[1] - 12F.dip2px()

View File

@ -27,6 +27,7 @@ import com.gh.common.chain.PackageCheckHandler;
import com.gh.common.chain.UnsupportedFeatureHandler;
import com.gh.common.chain.ValidateVSpaceHandler;
import com.gh.common.chain.VersionNumberHandler;
import com.gh.common.constant.Config;
import com.gh.common.filter.RegionSetting;
import com.gh.common.filter.RegionSettingHelper;
import com.gh.common.history.HistoryHelper;
@ -51,7 +52,6 @@ import com.gh.gamecenter.WebActivity;
import com.gh.gamecenter.common.entity.LinkEntity;
import com.gh.gamecenter.common.utils.DarkModeUtils;
import com.gh.gamecenter.common.utils.ExtensionsKt;
import com.gh.gamecenter.common.utils.FileUtils;
import com.gh.gamecenter.common.utils.NewFlatLogUtils;
import com.gh.gamecenter.common.utils.SensorsBridge;
import com.gh.gamecenter.core.utils.MtaHelper;
@ -69,14 +69,13 @@ import com.gh.gamecenter.gamedetail.dialog.GamePermissionDialogFragment;
import com.gh.gamecenter.manager.PackagesManager;
import com.gh.vspace.VHelper;
import com.lightgame.download.DownloadEntity;
import com.lightgame.download.FileUtils;
import com.lightgame.utils.Utils;
import java.io.File;
import java.util.ArrayList;
import java.util.List;
import kotlin.collections.CollectionsKt;
/**
* Created by khy on 12/02/18.
*/
@ -96,23 +95,13 @@ public class BindingAdapters {
}
}
public static void setDownloadButton(DownloadButton progressBar,
GameEntity gameEntity,
ExposureEvent traceEvent,
@Nullable View.OnClickListener clickCallBack,
@Nullable String entrance,
@Nullable String location) {
setDownloadButton(progressBar, gameEntity, traceEvent, clickCallBack, entrance, location, "其他");
}
// 大图下的进度条
public static void setDownloadButton(DownloadButton progressBar,
GameEntity gameEntity,
ExposureEvent traceEvent,
@Nullable View.OnClickListener clickCallBack,
@Nullable String entrance,
@Nullable String location,
String sourceEntrance) {
@Nullable String location) {
// 恢复DialogFragment
restoreDialogFragment(progressBar);
@ -133,7 +122,7 @@ public class BindingAdapters {
case DOWNLOADING_PLUGIN:
case DOWNLOADING_NORMAL:
Intent intent = DownloadManagerActivity.getDownloadMangerIntent(v.getContext(),
gameEntity.getApk().isEmpty() ? "" : gameEntity.getApk().get(0).getUrl(), entrance);
gameEntity.getApk().get(0).getUrl(), entrance);
v.getContext().startActivity(intent);
break;
case NONE:
@ -170,7 +159,7 @@ public class BindingAdapters {
builder.addHandler(new OverseaDownloadHandler());
builder.addHandler(new CheckDownloadHandler());
builder.setProcessEndCallback(gameEntity.getId(), (asVGame, isSubscribe) -> {
builder.setProcessEndCallback((asVGame, isSubscribe) -> {
download(v.getContext(),
progressBar,
gameEntity,
@ -195,7 +184,7 @@ public class BindingAdapters {
builder.addHandler(new GamePermissionHandler());
builder.addHandler(new VersionNumberHandler());
builder.setProcessEndCallback(gameEntity.getId(), (asVGame, isSubscribe) -> {
builder.setProcessEndCallback((asVGame, isSubscribe) -> {
DownloadDialog.showDownloadDialog(
v.getContext(),
gameEntity,
@ -219,7 +208,7 @@ public class BindingAdapters {
if (gameEntity.getApk().size() == 1) {
//启动模拟器游戏
if (SimulatorGameManager.isSimulatorGame(gameEntity)) {
DownloadEntity downloadEntity = SimulatorGameManager.findDownloadEntityByUrl(gameEntity.getApk().isEmpty() ? "" : gameEntity.getApk().get(0).getUrl());
DownloadEntity downloadEntity = SimulatorGameManager.findDownloadEntityByUrl(gameEntity.getApk().get(0).getUrl());
if (downloadEntity != null) {
File file = new File(downloadEntity.getPath());
if (!file.exists()) {
@ -279,7 +268,7 @@ public class BindingAdapters {
case RESERVABLE:
GamePermissionDialogFragment.show((AppCompatActivity) v.getContext(), gameEntity, gameEntity.getInfo(), () -> {
CheckLoginUtils.checkLogin(progressBar.getContext(), "", () -> {
ReservationHelper.reserve(v.getContext(), gameEntity, sourceEntrance, () -> {
ReservationHelper.reserve(v.getContext(), gameEntity.getId(), gameEntity.getName(), () -> {
LogUtils.logReservation(gameEntity, traceEvent);
updateReservation(progressBar, gameEntity);
});
@ -294,7 +283,7 @@ public class BindingAdapters {
});
});
} else {
ReservationHelper.showCancelReservationDialog(progressBar.getContext(),gameEntity, () -> {
ReservationHelper.showCancelReservationDialog(progressBar.getContext(), () -> {
ReservationHelper.cancelReservation(gameEntity, () -> {
updateReservation(progressBar, gameEntity);
});
@ -387,7 +376,7 @@ public class BindingAdapters {
case diskisfull:
case diskioerror:
case waiting:
progressBar.setText(com.gh.gamecenter.feature.R.string.downloading);
progressBar.setText(R.string.downloading);
if (downloadEntity.isPluggable() && PackagesManager.isInstalled(downloadEntity.getPackageName())) {
progressBar.setButtonStyle(DownloadButton.ButtonStyle.DOWNLOADING_PLUGIN);
} else {
@ -395,7 +384,7 @@ public class BindingAdapters {
}
break;
case done:
progressBar.setText(com.gh.gamecenter.feature.R.string.install);
progressBar.setText(R.string.install);
if (downloadEntity.isPluggable()
&& PackagesManager.isInstalled(downloadEntity.getPackageName())) {
progressBar.setButtonStyle(DownloadButton.ButtonStyle.INSTALL_PLUGIN);
@ -457,9 +446,9 @@ public class BindingAdapters {
ToastUtils.toast(context.getString(R.string.unsupported_browser_install_hint));
}
String buttonText = progressBar.getText();
ApkEntity apkEntity = CollectionsKt.firstOrNull(gameEntity.getApk());
String msg = FileUtils.isCanDownload(progressBar.getContext(), apkEntity == null ? "" : apkEntity.getSize());
if (apkEntity != null && TextUtils.isEmpty(msg)) {
ApkEntity apkEntity = gameEntity.getApk().get(0);
String msg = FileUtils.isCanDownload(progressBar.getContext(), apkEntity.getSize());
if (TextUtils.isEmpty(msg)) {
DownloadManager.createDownload(progressBar.getContext(),
apkEntity,
gameEntity,
@ -553,15 +542,15 @@ public class BindingAdapters {
gameName = String.format("%s - %s", game.getName(),
PlatformUtils.getInstance(view.getContext()).getPlatformName(
game.getApk().get(0).getPlatform()));
if (!gameName.equals((String) view.getTag(com.gh.gamecenter.common.R.string.tag_game_name_id))) {
if (!gameName.equals((String) view.getTag(R.string.tag_game_name_id))) {
view.setText(gameName);
view.setTag(com.gh.gamecenter.common.R.string.tag_game_name_id, gameName);
view.setTag(R.string.tag_game_name_id, gameName);
}
} else {
gameName = game.getName();
if (gameName != null && !gameName.equals((String) view.getTag(com.gh.gamecenter.common.R.string.tag_game_name_id))) {
if (gameName != null && !gameName.equals((String) view.getTag(R.string.tag_game_name_id))) {
view.setText(gameName);
view.setTag(com.gh.gamecenter.common.R.string.tag_game_name_id, gameName);
view.setTag(R.string.tag_game_name_id, gameName);
}
}

View File

@ -7,6 +7,7 @@ import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import com.gh.common.util.DirectUtils
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.fragment.BaseDialogFragment
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.utils.dip2px
@ -48,7 +49,7 @@ class ApplyModeratorDialogFragment : BaseDialogFragment() {
requireContext(),
startText.length,
startText.length + mGroupNumber.length,
com.gh.gamecenter.common.R.color.text_theme,
R.color.text_theme,
true
) {
DirectUtils.directToQqGroup(

View File

@ -40,7 +40,7 @@ import java.lang.ref.WeakReference
* 设备提醒弹窗
*/
class DeviceRemindDialog(context: Context, val entity: DeviceDialogEntity, val gameEntity: GameEntity) :
Dialog(context, com.gh.gamecenter.common.R.style.GhAlertDialog) {
Dialog(context, R.style.GhAlertDialog) {
private val mBinding: DialogDeviceRemindBinding by lazy { DialogDeviceRemindBinding.inflate(layoutInflater) }
private var currentPage = 0
private var mSlideLooperInterval = 3000L
@ -136,13 +136,13 @@ class DeviceRemindDialog(context: Context, val entity: DeviceDialogEntity, val g
val isFirst = SPUtils.getBoolean(Constants.SP_FIRST_DEVICE_REMIND, false)
if (!isFirst) {
mBinding.cancelTv.isEnabled = false
mBinding.cancelTv.background = ContextCompat.getDrawable(context, com.gh.gamecenter.common.R.drawable.button_round_f5f5f5)
mBinding.cancelTv.background = ContextCompat.getDrawable(context, R.drawable.button_round_f5f5f5)
disposable = countDownTimer(3) { finish, time ->
if (finish) {
mBinding.cancelTv.isEnabled = true
mBinding.cancelTv.background = ContextCompat.getDrawable(context, com.gh.gamecenter.common.R.drawable.button_blue_oval)
mBinding.cancelTv.background = ContextCompat.getDrawable(context, R.drawable.button_blue_oval)
mBinding.cancelTv.text = "我知道了"
mBinding.cancelTv.setTextColor(ContextCompat.getColor(context, com.gh.gamecenter.common.R.color.white))
mBinding.cancelTv.setTextColor(ContextCompat.getColor(context, R.color.white))
} else {
mBinding.cancelTv.text = "我知道了(${time}S)"
}
@ -153,8 +153,8 @@ class DeviceRemindDialog(context: Context, val entity: DeviceDialogEntity, val g
mBinding.noRemindAgainCb.visibility = View.VISIBLE
mBinding.cancelTv.text = "我知道了"
mBinding.cancelTv.isEnabled = true
mBinding.cancelTv.setTextColor(ContextCompat.getColor(context, com.gh.gamecenter.common.R.color.white))
mBinding.cancelTv.background = ContextCompat.getDrawable(context, com.gh.gamecenter.common.R.drawable.button_blue_oval)
mBinding.cancelTv.setTextColor(ContextCompat.getColor(context, R.color.white))
mBinding.cancelTv.background = ContextCompat.getDrawable(context, R.drawable.button_blue_oval)
}
mBinding.cancelTv.setOnClickListener {
SPUtils.setBoolean(Constants.SP_NO_REMIND_AGAIN, mBinding.noRemindAgainCb.isChecked)

View File

@ -14,6 +14,7 @@ import com.gh.gamecenter.common.base.fragment.BaseDialogFragment
import com.gh.common.util.DirectUtils
import com.gh.gamecenter.common.utils.dip2px
import com.gh.gamecenter.common.utils.toColor
import com.gh.gamecenter.R
import com.gh.gamecenter.databinding.DialogGameOffServiceBinding
import com.gh.gamecenter.feature.entity.GameEntity
@ -22,7 +23,6 @@ class GameOffServiceDialogFragment : BaseDialogFragment() {
private var mDialog: GameEntity.Dialog? = null
private var mBinding: DialogGameOffServiceBinding? = null
private var mCallback: (() -> Unit)? = null
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
@ -44,7 +44,6 @@ class GameOffServiceDialogFragment : BaseDialogFragment() {
titleTv.text = title
contentTv.text = HtmlCompat.fromHtml(content, HtmlCompat.FROM_HTML_MODE_LEGACY)
okTv.setOnClickListener {
mCallback?.invoke()
dismissAllowingStateLoss()
}
@ -61,10 +60,11 @@ class GameOffServiceDialogFragment : BaseDialogFragment() {
if (index == notEmptySite.size - 1) bottomMargin = 8F.dip2px()
}
siteTv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 14F)
siteTv.setTextColor(com.gh.gamecenter.common.R.color.text_theme.toColor(requireContext()))
siteTv.setTextColor(R.color.text_theme.toColor(requireContext()))
siteTv.text = site.text
siteTv.paintFlags = siteTv.paintFlags or Paint.UNDERLINE_TEXT_FLAG
siteTv.setOnClickListener {
// MtaHelper.onEvent("游戏下载状态按钮", getKey(), site.text)
DirectUtils.directToWebView(requireContext(), site.url, "(关闭下载弹窗)")
dismissAllowingStateLoss()
}
@ -83,13 +83,11 @@ class GameOffServiceDialogFragment : BaseDialogFragment() {
const val KEY_DIALOG = "dialog"
@JvmStatic
fun getInstance(dialog: GameEntity.Dialog, callback: (() -> Unit)? = null) =
GameOffServiceDialogFragment().apply {
arguments = Bundle().apply {
putParcelable(KEY_DIALOG, dialog)
}
mCallback = callback
fun getInstance(dialog: GameEntity.Dialog) = GameOffServiceDialogFragment().apply {
arguments = Bundle().apply {
putParcelable(KEY_DIALOG, dialog)
}
}
}
}

View File

@ -158,7 +158,7 @@ class InstallPermissionDialogFragment : BaseDialogFragment() {
}
if (isXapk) {
val xapkUnzipVersions = Config.getSettings()?.permissionPopupAppliedVersions?.xapkUnzip
if (xapkUnzipVersions?.contains(Build.VERSION.SDK_INT.toString()) == false || XapkInstaller.systemHasFlaw) {
if (xapkUnzipVersions?.contains(Build.VERSION.SDK_INT.toString()) == false) {
callBack?.invoke(false)
return
}

View File

@ -76,12 +76,12 @@ class NewPrivacyPolicyDialogFragment : BaseDialogFragment() {
contentText.setSpan(object : ClickableSpan() {
override fun updateDrawState(ds: TextPaint) {
super.updateDrawState(ds)
ds.color = ContextCompat.getColor(requireContext(), com.gh.gamecenter.common.R.color.text_theme)
ds.color = ContextCompat.getColor(requireContext(), R.color.text_theme)
ds.isUnderlineText = false
}
override fun onClick(widget: View) {
val privacyPolicyUrl = requireContext().getString(com.gh.gamecenter.common.R.string.privacy_policy_url)
val privacyPolicyUrl = requireContext().getString(R.string.privacy_policy_url)
val childrenPrivacyPolicyUrl = requireContext().getString(R.string.children_policy_url)
val thirdPartySdkUrl = requireContext().getString(R.string.sdk_list_url)
val permissionListUrl = requireContext().getString(R.string.permission_and_usage_url)

View File

@ -19,9 +19,9 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.util.DirectUtils
import com.gh.common.util.LogUtils
import com.gh.common.util.PackageHelper
import com.gh.common.util.PackageUtils
import com.gh.download.DownloadManager
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.BaseRecyclerViewHolder
import com.gh.gamecenter.common.callback.ConfirmListener
import com.gh.gamecenter.common.constant.Constants
@ -59,7 +59,7 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
private val mDuration = 3000
private var mDisposable: Disposable? = null
private var mAdapter: PackageCheckAdapter? = null
private var mAllInstalledPackages = PackageHelper.getInstalledPackageNameList(HaloApp.getInstance().application, 0)
private var mAllInstalledPackages = PackageUtils.getInstalledPackages(HaloApp.getInstance().application, 0)
var gameEntity: GameEntity? = null
var callBack: ConfirmListener? = null
@ -125,7 +125,7 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
requireContext(),
0,
(link.title ?: "").length,
com.gh.gamecenter.common.R.color.text_theme,
R.color.text_theme,
true
) {
LogUtils.uploadPackageCheck(
@ -284,7 +284,7 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
if (it >= mDuration) {
mDisposable?.dispose()
binding.downloadBtn.isEnabled = true
binding.downloadBtn.background = com.gh.gamecenter.common.R.drawable.bg_notification_open_btn_style_2.toDrawable()
binding.downloadBtn.background = R.drawable.bg_notification_open_btn_style_2.toDrawable()
}
}
val animator = ValueAnimator.ofInt(0, 100)
@ -325,7 +325,7 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
override fun onResume() {
super.onResume()
mAllInstalledPackages = PackageHelper.getInstalledPackageNameList(HaloApp.getInstance().application, 0)
mAllInstalledPackages = PackageUtils.getInstalledPackages(HaloApp.getInstance().application, 0)
gameEntity?.packageDialog?.let {
if (isAllPackageInstalled(mAllInstalledPackages, it)) {
callBack?.onConfirm()
@ -363,7 +363,7 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
@Subscribe(threadMode = ThreadMode.MAIN)
fun onEventMainThread(busFour: EBPackage) {
if (busFour.isInstalledOrUninstalled()) {
mAllInstalledPackages = PackageHelper.getInstalledPackageNameList(HaloApp.getInstance().application, 0)
mAllInstalledPackages = PackageUtils.getInstalledPackages(HaloApp.getInstance().application, 0)
mAdapter?.notifyDataSetChanged()
}
}
@ -391,10 +391,10 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
val isAllInstalled = checkDetectionsInstalled(mAllInstalledPackages, entity.packages)
if (isAllInstalled) {
holder.binding.statusTv.text = "已安装"
holder.binding.statusTv.setTextColor(ContextCompat.getColor(context, com.gh.gamecenter.common.R.color.text_theme))
holder.binding.statusTv.setTextColor(ContextCompat.getColor(context, R.color.text_theme))
} else {
holder.binding.statusTv.text = "未安装"
holder.binding.statusTv.setTextColor(ContextCompat.getColor(context, com.gh.gamecenter.common.R.color.secondary_red))
holder.binding.statusTv.setTextColor(ContextCompat.getColor(context, R.color.secondary_red))
}
holder.binding.statusTv.visibility = View.VISIBLE
} else {
@ -416,7 +416,7 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
return
}
val allInstalledPackages = PackageHelper.getInstalledPackageNameList(HaloApp.getInstance().application, 0)
val allInstalledPackages = PackageUtils.getInstalledPackages(HaloApp.getInstance().application, 0)
if (isAllPackageInstalled(allInstalledPackages, packageDialogEntity)) {
callBack.onConfirm()
return
@ -453,12 +453,12 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
}
private fun checkDetectionsInstalled(
allInstalledPackages: List<String>,
allInstalledPackages: List<PackageInfo>,
packages: ArrayList<String>
): Boolean {
var isPackagesInstalled = false
packages.forEach { packageName ->
val isInstalled = allInstalledPackages.find { it == packageName } != null
val isInstalled = allInstalledPackages.find { it.packageName == packageName } != null
if (isInstalled) {
isPackagesInstalled = true
return@forEach
@ -469,7 +469,7 @@ class PackageCheckDialogFragment : BaseDialogFragment() {
fun isAllPackageInstalled(
allInstalledPackages: List<String>,
allInstalledPackages: List<PackageInfo>,
packageDialogEntity: PackageDialogEntity
): Boolean {
var isAllInstalled = true

View File

@ -12,6 +12,7 @@ import android.view.*
import androidx.core.content.ContextCompat
import androidx.fragment.app.FragmentActivity
import androidx.fragment.app.FragmentTransaction
import com.gh.gamecenter.R
import com.gh.gamecenter.WebActivity
import com.gh.gamecenter.common.base.fragment.BaseDialogFragment
import com.gh.gamecenter.common.constant.Constants
@ -67,13 +68,13 @@ class PrivacyPolicyDialogFragment : BaseDialogFragment() {
skipText.setSpan(object : ClickableSpan() {
override fun updateDrawState(ds: TextPaint) {
super.updateDrawState(ds)
ds.color = ContextCompat.getColor(requireContext(), com.gh.gamecenter.common.R.color.text_theme)
ds.color = ContextCompat.getColor(requireContext(), R.color.text_theme)
ds.isUnderlineText = false
}
override fun onClick(widget: View) {
val intent =
WebActivity.getIntent(requireContext(), context!!.getString(com.gh.gamecenter.common.R.string.privacy_policy_url), true)
WebActivity.getIntent(requireContext(), context!!.getString(R.string.privacy_policy_url), true)
context?.startActivity(intent)
}
}, skipText.length - 6, skipText.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
@ -109,13 +110,13 @@ class PrivacyPolicyDialogFragment : BaseDialogFragment() {
skipText.setSpan(object : ClickableSpan() {
override fun updateDrawState(ds: TextPaint) {
super.updateDrawState(ds)
ds.color = ContextCompat.getColor(requireContext(), com.gh.gamecenter.common.R.color.text_theme)
ds.color = ContextCompat.getColor(requireContext(), R.color.text_theme)
ds.isUnderlineText = false
}
override fun onClick(widget: View) {
val intent =
WebActivity.getIntent(requireContext(), context!!.getString(com.gh.gamecenter.common.R.string.privacy_policy_url), true)
WebActivity.getIntent(requireContext(), context!!.getString(R.string.privacy_policy_url), true)
context?.startActivity(intent)
}
}, skipText.length - 9, skipText.length - 5, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)
@ -123,12 +124,12 @@ class PrivacyPolicyDialogFragment : BaseDialogFragment() {
skipText.setSpan(object : ClickableSpan() {
override fun updateDrawState(ds: TextPaint) {
super.updateDrawState(ds)
ds.color = ContextCompat.getColor(requireContext(), com.gh.gamecenter.common.R.color.text_theme)
ds.color = ContextCompat.getColor(requireContext(), R.color.text_theme)
ds.isUnderlineText = false
}
override fun onClick(widget: View) {
val intent = WebActivity.getIntent(requireContext(), context!!.getString(com.gh.gamecenter.common.R.string.disclaimer_url), true)
val intent = WebActivity.getIntent(requireContext(), context!!.getString(R.string.disclaimer_url), true)
context?.startActivity(intent)
}
}, skipText.length - 4, skipText.length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE)

View File

@ -1,42 +1,27 @@
package com.gh.common.dialog
import android.content.Context
import android.content.DialogInterface
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.recyclerview.widget.GridLayoutManager
import androidx.recyclerview.widget.RecyclerView
import com.gh.common.exposure.ExposureListener
import com.gh.common.exposure.IExposable
import com.gh.gamecenter.DownloadManagerActivity
import com.gh.gamecenter.GameDetailActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.BaseRecyclerViewHolder
import com.gh.gamecenter.common.base.fragment.BaseDialogFragment
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.exposure.ExposureSource
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.utils.ImageUtils
import com.gh.gamecenter.common.utils.fromHtml
import com.gh.gamecenter.GameDetailActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.common.view.FixLinearLayoutManager
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.core.utils.SPUtils.getBoolean
import com.gh.gamecenter.databinding.DialogReserveBinding
import com.gh.gamecenter.databinding.DialogReserveItemBinding
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.entity.ReserveOnlineEntity
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.common.entity.SimpleGameEntity
import com.gh.gamecenter.mygame.MyGameActivity
import com.halo.assistant.HaloApp
import com.lightgame.adapter.BaseRecyclerAdapter
class ReserveDialog : BaseDialogFragment() {
private lateinit var reserveOnlineEntity: ReserveOnlineEntity
val games: List<GameEntity>
get() = reserveOnlineEntity.games
private lateinit var mReserveList: List<SimpleGameEntity>
private var mDismissListener: (() -> Unit)? = null
override fun onCreate(savedInstanceState: Bundle?) {
@ -51,162 +36,66 @@ class ReserveDialog : BaseDialogFragment() {
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View {
val binding: DialogReserveBinding = DialogReserveBinding.inflate(layoutInflater, null, false)
reserveOnlineEntity = arguments?.getParcelable(RESERVE_ONLINE) ?: ReserveOnlineEntity()
mReserveList = arguments?.getParcelableArrayList(RESERVE_LIST) ?: arrayListOf()
binding.tvTitle.text =
resources.getString(R.string.dialog_reserve_title, reserveOnlineEntity.gamesTotal).fromHtml()
binding.tvViewAllAppointment.setOnClickListener {
SensorsBridge.trackAppointmentGameOnlineDialogClick(buttonName = "查看全部预约")
val intent = MyGameActivity.getIntentWithConfig(requireContext(), MyGameActivity.RESERVATION_INDEX)
binding.title.text = resources.getString(R.string.dialog_reserve_title, mReserveList.size).fromHtml()
binding.more.visibility = if (mReserveList.size > 4) {
View.VISIBLE
} else View.GONE
binding.more.setOnClickListener {
val intent = MyGameActivity.getIntentWithConfig(requireContext(), 2)
startActivity(intent)
}
val adapter = ReserveDialogAdapter(requireContext(), games)
binding.rvGames.layoutManager = FixLinearLayoutManager(context, RecyclerView.HORIZONTAL, false)
binding.rvGames.adapter = adapter
val exposureListener = ExposureListener(this, adapter)
binding.rvGames.addOnScrollListener(exposureListener)
binding.ivClose.setOnClickListener {
dismissAllowingStateLoss()
}
binding.recyclerView.layoutManager = if (mReserveList.size > 4) {
GridLayoutManager(context, 4)
} else {
FixLinearLayoutManager(context, RecyclerView.HORIZONTAL, false)
}
binding.recyclerView.adapter = object : BaseRecyclerAdapter<ReserveDialogItemViewHolder>(context) {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ReserveDialogItemViewHolder {
val inflate = mLayoutInflater.inflate(R.layout.dialog_reserve_item, parent, false)
return ReserveDialogItemViewHolder(DialogReserveItemBinding.bind(inflate))
}
checkHasAutoDownload(binding)
override fun getItemCount(): Int {
return if (mReserveList.size > 4) 4 else mReserveList.size
}
override fun onBindViewHolder(holder: ReserveDialogItemViewHolder, position: Int) {
val entity = mReserveList[position]
ImageUtils.display(holder.binding.icon, entity.icon)
holder.binding.gameNameTv.text = entity.name
holder.itemView.setOnClickListener {
GameDetailActivity.startGameDetailActivity(mContext, entity.id, "(预约弹窗)")
dismissAllowingStateLoss()
}
}
}
dialog?.setCanceledOnTouchOutside(true)
return binding.root
}
private fun checkHasAutoDownload(binding: DialogReserveBinding) {
if (reserveOnlineEntity.wifiAutoDownloadTotal > 0) {
// 开启自动下载
binding.tvAutoDownloadTips.goneIf(false)
var firstAutoDownloadGameName =
reserveOnlineEntity.games.find { it.wifiAutoDownload && !it.isLandPageAddressDialog() }?.name
if(!firstAutoDownloadGameName.isNullOrBlank() && firstAutoDownloadGameName.length > GAME_NAME_SHOW_MAX_LENGTH){
firstAutoDownloadGameName = "${firstAutoDownloadGameName.take(GAME_NAME_SHOW_MAX_LENGTH-1)}..."
}
val isWifiOpen = NetworkUtils.isWifiConnected(HaloApp.getInstance())
binding.tvAutoDownloadTips.text =
if (isWifiOpen) {
if (firstAutoDownloadGameName.isNullOrBlank()) {
getString(
R.string.reserve_reminder_auto_download,
"${reserveOnlineEntity.wifiAutoDownloadTotal}"
)
} else {
getString(
R.string.reserve_reminder_auto_download_with_name,
firstAutoDownloadGameName,
"${reserveOnlineEntity.wifiAutoDownloadTotal}"
)
}
} else {
if (firstAutoDownloadGameName.isNullOrBlank()) {
getString(
R.string.reserve_reminder_wait_for_wifi_to_auto_download,
"${reserveOnlineEntity.wifiAutoDownloadTotal}"
)
} else {
getString(
R.string.reserve_reminder_wait_for_wifi_to_auto_download_with_name,
firstAutoDownloadGameName,
"${reserveOnlineEntity.wifiAutoDownloadTotal}"
)
}
}
binding.tvAutoDownloadTips.setOnClickListener {
SensorsBridge.trackAppointmentGameOnlineDialogClick(buttonName = "查看进度")
val intent = DownloadManagerActivity.getDownloadMangerIntent(requireContext(), "")
startActivity(intent)
}
} else {
binding.tvAutoDownloadTips.goneIf(true)
}
}
fun setOnDismissListener(dismissListener: () -> Unit) {
mDismissListener = dismissListener
}
override fun onDismiss(dialog: DialogInterface) {
super.onDismiss(dialog)
SensorsBridge.trackAppointmentGameOnlineDialogClick(buttonName = "关闭弹窗")
}
override fun onStart() {
super.onStart()
dialog?.window?.let {
it.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
val params = it.attributes
params.width = DisplayUtils.dip2px(300F)
it.attributes = params
}
}
override fun onDestroy() {
super.onDestroy()
mDismissListener?.invoke()
}
companion object {
const val RESERVE_ONLINE = "reserve_online"
private const val GAME_NAME_SHOW_MAX_LENGTH = 8
const val RESERVE_LIST = "reserve_list"
@JvmStatic
fun getInstance(reserveOnlineEntity: ReserveOnlineEntity?) = ReserveDialog().apply {
arguments = Bundle().apply {
putParcelable(RESERVE_ONLINE, reserveOnlineEntity)
}
fun getInstance(reserveList: List<SimpleGameEntity>) = ReserveDialog().apply {
arguments = Bundle()
arguments?.putParcelableArrayList(RESERVE_LIST, ArrayList(reserveList))
}
}
}
class ReserveDialogAdapter(
context: Context,
private val games: List<GameEntity>
) :
BaseRecyclerAdapter<ReserveDialogItemViewHolder>(context), IExposable {
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ReserveDialogItemViewHolder {
return ReserveDialogItemViewHolder(parent.toBinding())
}
override fun getItemCount(): Int {
return if (games.size > 8) 8 else games.size
}
override fun onBindViewHolder(holder: ReserveDialogItemViewHolder, position: Int) {
val entity = games[position]
holder.binding.icon.displayGameIcon(entity)
holder.binding.gameNameTv.text = entity.name
holder.itemView.setOnClickListener {
SensorsBridge.trackAppointmentGameOnlineDialogClick(
"游戏",
entity.id,
entity.name ?: "",
entity.categoryChinese,
)
GameDetailActivity.startGameDetailActivity(mContext, entity.id, "(预约弹窗)", entity.exposureEvent)
}
entity.exposureEvent = ExposureEvent.createEvent(
entity,
listOf(ExposureSource("预约上线弹窗", ""))
)
}
override fun getEventByPosition(pos: Int): ExposureEvent? {
return games.getOrNull(pos)?.exposureEvent
}
override fun getEventListByPosition(pos: Int): List<ExposureEvent>? {
return null
}
}
class ReserveDialogItemViewHolder(val binding: DialogReserveItemBinding) : BaseRecyclerViewHolder<Any>(binding.root)

View File

@ -1,278 +0,0 @@
package com.gh.common.dialog
import android.app.Dialog
import android.content.Context
import android.os.Bundle
import android.text.InputFilter
import android.view.LayoutInflater
import androidx.core.widget.addTextChangedListener
import com.gh.gamecenter.R
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.common.retrofit.Response
import com.gh.gamecenter.common.utils.singleToMain
import com.gh.gamecenter.common.utils.toColor
import com.gh.gamecenter.common.utils.toResString
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.databinding.DialogReserveReminderPhoneNumberBinding
import com.gh.gamecenter.entity.ReserveModifyEntity
import com.gh.gamecenter.entity.ValidateCodeResponse
import com.halo.assistant.fragment.reserve.OnReserveReminderListener
import com.halo.assistant.fragment.reserve.ReserveReminderRepository
import io.reactivex.Observable
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
import okhttp3.ResponseBody
import org.json.JSONObject
import retrofit2.HttpException
import java.util.concurrent.TimeUnit
class ReserveReminderPhoneNumberDialog(
context: Context,
themeResId: Int,
private val dialogType: Int,
private val phoneNumber: String,
private var serviceId: String,
private val gameId: String,
private val repository: ReserveReminderRepository,
private val listener: OnReserveReminderListener
) :
Dialog(context, themeResId) {
private val compositeDisposable = CompositeDisposable()
private lateinit var binding: DialogReserveReminderPhoneNumberBinding
private var hasValidated = false
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DialogReserveReminderPhoneNumberBinding.inflate(LayoutInflater.from(context))
setContentView(binding.root)
initView()
}
private fun initView() {
binding.vClose.setOnClickListener {
dismiss()
}
setSubmitState(phoneNumber)
binding.etInput.addTextChangedListener {
val content = binding.etInput.text?.toString() ?: ""
if (dialogType == DIALOG_TYPE_BIND_PHONE || dialogType == DIALOG_TYPE_CHANGE_PHONE) {
setSubmitState(content)
} else {
val length = content.length
if (length == VALIDATE_CODE_LENGTH) {
verifyPhoneNumber(content)
}
}
}
when (dialogType) {
DIALOG_TYPE_BIND_PHONE -> {
binding.tvTitle.setText(R.string.enable_sms_reminder)
binding.tvDescription.setText(R.string.enable_sms_reminder_description)
binding.etInput.setText(phoneNumber)
binding.etInput.setHint(com.gh.gamecenter.login.R.string.input_phone_hint)
}
DIALOG_TYPE_CHANGE_PHONE -> {
binding.tvTitle.setText(R.string.change_phone_number_2)
binding.tvDescription.setText(R.string.enable_sms_reminder_description)
binding.etInput.setText(phoneNumber)
binding.etInput.setHint(com.gh.gamecenter.login.R.string.input_phone_hint)
}
DIALOG_TYPE_VERIFY_PHONE -> {
startCountDown()
binding.tvTitle.setText(R.string.please_input_sms_verify_code)
if (phoneNumber.length == PHONE_NUMBER_LENGTH) {
val phoneNumberWithMask = phoneNumber.substring(0, 3) + MASK + phoneNumber.substring(7)
binding.tvDescription.text =
context.getString(R.string.verify_code_send_with_phone_number, phoneNumberWithMask)
}
binding.tvSubmit.alpha = 1.0F
binding.etInput.filters = arrayOf<InputFilter>(InputFilter.LengthFilter(VALIDATE_CODE_LENGTH))
binding.etInput.setHint(R.string.please_input_verify_code)
}
}
binding.tvSubmit.setOnClickListener {
val text = binding.etInput.text?.toString() ?: ""
if (dialogType == DIALOG_TYPE_VERIFY_PHONE) {
resendValidateCode()
} else {
if (isEnableSubmit(text)) {
when (dialogType) {
DIALOG_TYPE_BIND_PHONE -> bindPhoneNumber(text)
DIALOG_TYPE_CHANGE_PHONE -> bindPhoneNumber(text)
}
} else {
if (text != phoneNumber) {
ToastUtils.toast(R.string.invalid_phone_number_format.toResString())
}
}
}
}
}
private fun resendValidateCode() {
repository.sendVerifyCode(phoneNumber)
.compose(singleToMain())
.subscribe(object : BiResponse<ValidateCodeResponse>() {
override fun onSuccess(data: ValidateCodeResponse) {
serviceId = data.serviceId
startCountDown()
}
}).let(compositeDisposable::add)
}
private fun verifyPhoneNumber(content: String) {
repository.verifyPhoneNumber(phoneNumber, content, serviceId)
.compose(singleToMain())
.subscribe(object : BiResponse<ResponseBody>() {
override fun onSuccess(data: ResponseBody) {
hasValidated = true
listener.phoneNumberValidateSuccessfully()
ToastUtils.toast(R.string.phone_number_validate_successfully.toResString())
dismiss()
}
override fun onFailure(exception: Exception) {
super.onFailure(exception)
binding.etInput.text = null
ToastUtils.toast(R.string.phone_number_validate_failure.toResString())
}
}).let(compositeDisposable::add)
}
private fun bindPhoneNumber(phone: String) {
repository.bindPhone(gameId, phone)
.compose(singleToMain())
.subscribe(object : BiResponse<ReserveModifyEntity>() {
override fun onSuccess(data: ReserveModifyEntity) {
listener.bindPhoneSuccessfully(data.smsConfig.mobileValidated, phone)
dismiss()
}
override fun onFailure(exception: Exception) {
super.onFailure(exception)
if (exception is HttpException) {
try {
val string = exception.response().errorBody()?.string()
if (!string.isNullOrBlank()) {
val json = JSONObject(string)
val message = json.getJSONObject("toast").getString("sms_config.mobile")
ToastUtils.showToast(message)
}
} catch (e: Exception) {
// no implement
}
}
}
}).let(compositeDisposable::add)
}
private fun startCountDown() {
binding.tvSubmit.isEnabled = false
binding.tvSubmit.setBackgroundResource(com.gh.gamecenter.common.R.drawable.bg_common_button_light_fill_gray)
binding.tvSubmit.setTextColor(com.gh.gamecenter.common.R.color.text_tertiary.toColor(context))
Observable.interval(0, 1, TimeUnit.SECONDS)
.take(COUNT_DOWN_DURATION)
.map {
COUNT_DOWN_DURATION - it
}
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : Response<Long>() {
override fun onSubscribe(d: Disposable) {
compositeDisposable.add(d)
}
override fun onNext(time: Long) {
binding.tvSubmit.text = context.getString(R.string.resend_with_time, "$time")
}
override fun onComplete() {
binding.tvSubmit.isEnabled = true
binding.tvSubmit.setBackgroundResource(com.gh.gamecenter.common.R.drawable.bg_common_button_fill_blue)
binding.tvSubmit.setTextColor(com.gh.gamecenter.common.R.color.text_aw_primary.toColor(context))
binding.tvSubmit.setText(R.string.resend)
}
})
}
override fun dismiss() {
compositeDisposable.clear()
if (dialogType == DIALOG_TYPE_VERIFY_PHONE && !hasValidated) {
ToastUtils.toast(R.string.phone_number_validate_cancel.toResString())
}
super.dismiss()
}
private fun isEnableSubmit(phone: String) =
PHONE_NUMBER_PATTERN.toRegex().matches(phone)
&& if (dialogType == DIALOG_TYPE_CHANGE_PHONE) phone != phoneNumber else true
private fun setSubmitState(phone: String) {
val isEnable = isEnableSubmit(phone)
binding.tvSubmit.alpha = if (isEnable) {
TV_SUBMIT_ENABLE_ALPHA
} else {
TV_SUBMIT_UNABLE_ALPHA
}
}
companion object {
private const val PHONE_NUMBER_PATTERN = "^1\\d{10}$"
private const val MASK = "****"
private const val PHONE_NUMBER_LENGTH = 11
private const val VALIDATE_CODE_LENGTH = 6
const val DIALOG_TYPE_BIND_PHONE = 0
const val DIALOG_TYPE_CHANGE_PHONE = 1
const val DIALOG_TYPE_VERIFY_PHONE = 2
private const val COUNT_DOWN_DURATION = 60L
private const val TV_SUBMIT_ENABLE_ALPHA = 1F
private const val TV_SUBMIT_UNABLE_ALPHA = 0.4F
fun create(
context: Context,
dialogType: Int,
phoneNumber: String,
serviceId: String,
gameId: String,
repository: ReserveReminderRepository,
listener: OnReserveReminderListener
) =
ReserveReminderPhoneNumberDialog(
context,
com.gh.gamecenter.common.R.style.DialogWindowTransparent,
dialogType,
phoneNumber,
serviceId,
gameId,
repository,
listener
)
}
}

View File

@ -1,428 +0,0 @@
package com.gh.common.dialog
import android.app.Dialog
import android.content.Context
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.os.Handler
import android.os.Looper
import android.text.TextUtils
import android.view.*
import android.view.ViewGroup.MarginLayoutParams
import androidx.core.view.updateLayoutParams
import com.gh.common.pop.EditBindPhoneInfoPop
import com.gh.common.pop.EditBindWechatPop
import com.gh.common.pop.RealNameTipsPop
import com.gh.gamecenter.R
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.utils.dip2px
import com.gh.gamecenter.common.utils.goneIf
import com.gh.gamecenter.common.utils.toObject
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.databinding.*
import com.gh.gamecenter.entity.ReserveReminderEntity
import com.gh.gamecenter.login.entity.UserInfoEntity
import com.gh.gamecenter.login.user.UserManager
import com.halo.assistant.HaloApp
import com.halo.assistant.fragment.reserve.OnReserveReminderListener
class ReserveSuccessReminderDialog(
context: Context,
themeResId: Int,
private val listener: OnReserveReminderListener
) :
Dialog(context, themeResId), OnReserveSuccessListener {
private var reserveReminder = ReserveReminderEntity()
private val handler = Handler(Looper.getMainLooper())
private val handlers = arrayListOf<ReminderContentHandler>()
private lateinit var binding: DialogReserveSuccessWithSmsBinding
private val realNameQuestionPop by lazy {
RealNameTipsPop.create(context, listener)
}
private var hasAutoPopped = false
private var isInit = true
override fun onTouchEvent(event: MotionEvent): Boolean {
if (event.action == MotionEvent.ACTION_UP) {
if (realNameQuestionPop.isShowing) {
realNameQuestionPop.dismiss()
return true
} else if (handlers.any { it.hasPopShowing }) {
handlers.forEach {
it.dismissPop()
}
return true
}
}
return super.onTouchEvent(event)
}
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
binding = DialogReserveSuccessWithSmsBinding.inflate(LayoutInflater.from(context))
setContentView(binding.root)
binding.ivClose.setOnClickListener {
dismiss()
}
binding.ivQuestion.setOnClickListener {
realNameQuestionPop.showAtLocation(binding.cbAutoDownload, Gravity.BOTTOM, 0, 4F.dip2px())
}
}
private fun initView() {
handlers.clear()
binding.flContentContainer.removeAllViews()
val smsConfig = reserveReminder.smsConfig
val wechatConfig = reserveReminder.wechatConfig
when {
reserveReminder.onlyShowWechatReminder && !wechatConfig.isReminderEnable -> { // 只显示微信:未开启
binding.tvContent.setText(R.string.reverse_success_without_reminder_tips)
arrayListOf(OnlyWechatReminderUnableHandler(16.dp, binding.flContentContainer, this))
}
reserveReminder.onlyShowWechatReminder && wechatConfig.isReminderEnable -> { // 只显示微信:已开
binding.tvContent.setText(R.string.reverse_success_with_reminder_tips)
arrayListOf(
WechatReminderEnableHandler(
reserveReminder.wechatConfig.nickName,
8.dp,
binding.flContentContainer,
this
)
)
}
!smsConfig.notice && !wechatConfig.isReminderEnable -> { // 短信,微信未开启
binding.tvContent.setText(R.string.reverse_success_without_reminder_tips)
arrayListOf(
SmsReminderUnableHandler(16.dp, binding.flContentContainer, this),
WechatReminderUnableHandler(8.dp, binding.flContentContainer, this)
)
}
smsConfig.notice && wechatConfig.isReminderEnable -> {// 短信,微信已开启
binding.tvContent.setText(R.string.reverse_success_with_reminder_tips)
arrayListOf(
SmsReminderEnableHandler(reserveReminder.smsConfig, 8.dp, binding.flContentContainer, this),
WechatReminderEnableHandler(
reserveReminder.wechatConfig.nickName,
8.dp,
binding.flContentContainer,
this
)
)
}
smsConfig.notice && !wechatConfig.isReminderEnable -> { // 短信开启,微信未开启
binding.tvContent.setText(R.string.reverse_success_with_reminder_tips)
arrayListOf(
SmsReminderEnableHandler(smsConfig, 8.dp, binding.flContentContainer, this),
WechatReminderUnableHandler(16.dp, binding.flContentContainer, this)
)
}
!smsConfig.notice && wechatConfig.isReminderEnable -> { // 微信开启,短信未开启
binding.tvContent.setText(R.string.reverse_success_with_reminder_tips)
arrayListOf(
WechatReminderEnableHandler(
wechatConfig.nickName,
8.dp,
binding.flContentContainer,
this
),
SmsReminderUnableHandler(16.dp, binding.flContentContainer, this)
)
}
else -> {
binding.tvContent.setText(R.string.reverse_success_without_reminder_tips)
arrayListOf()
}
}.let {
handlers.clear()
handlers.addAll(it)
}
handlers.forEach {
binding.flContentContainer.addView(it.init())
}
if (isInit) {
isInit = false
binding.gAutoDownload.goneIf(!reserveReminder.isEnableAutoDownload)
if (reserveReminder.isEnableAutoDownload) {
binding.cbAutoDownload.isChecked = reserveReminder.wifiAutoDownload
checkIfShowRealNamePop()
}
binding.cbAutoDownload.setOnCheckedChangeListener { _, isChecked ->
listener.enableAutoDownload(isChecked)
checkIfShowRealNamePop()
}
}
}
private fun checkIfShowRealNamePop() {
if (hasAutoPopped) {
return
}
hasAutoPopped = true
handler.postDelayed({
val idCard = UserManager.getInstance().userInfoEntity?.idCard
if (idCard != null && idCard.status != 1 && idCard.minor != true) {
// 账号已实名
return@postDelayed
}
val deviceCertificationInfoString =
SPUtils.getString(Constants.SP_DEVICE_CERTIFICATION_PREFIX + HaloApp.getInstance().gid)
if (!TextUtils.isEmpty(deviceCertificationInfoString)) {
val deviceIdCard = deviceCertificationInfoString.toObject<UserInfoEntity>()?.idCard
if (deviceIdCard != null && deviceIdCard.status != 1 && deviceIdCard.minor != true) {
// 设备已实名
return@postDelayed
}
}
realNameQuestionPop.showAtLocation(binding.cbAutoDownload, Gravity.BOTTOM, 0, 0)
}, 16)
}
override fun updateSmsReminder(isEnable: Boolean) {
listener.updateSmsReminder(isEnable)
}
override fun updateWechatReminder() {
listener.updateWechatReminder()
}
override fun changePhoneNumber() {
listener.changedPhoneNumber()
}
override fun verifyPhoneNumber() {
listener.verifyPhoneNumber()
}
override fun changeWechatBinding() {
listener.changeWechatBinding()
}
override fun onStart() {
super.onStart()
window?.let {
it.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
val params = it.attributes
params.width = DisplayUtils.dip2px(300F)
it.attributes = params
}
}
fun updateReserveReminder(reserveReminder: ReserveReminderEntity) {
this.reserveReminder = reserveReminder
initView()
}
override fun dismiss() {
handler.removeCallbacksAndMessages(null)
super.dismiss()
}
companion object {
private val Int.dp: Int
get() = DisplayUtils.dip2px(this.toFloat())
fun create(context: Context, listener: OnReserveReminderListener) =
ReserveSuccessReminderDialog(
context,
com.gh.gamecenter.common.R.style.DialogWindowTransparent,
listener
).apply {
}
}
abstract class ReminderContentHandler(
val topMargin: Int,
val parent: ViewGroup,
val listener: OnReserveSuccessListener
) {
open val hasPopShowing: Boolean = false
fun init(): View {
val root = createView(LayoutInflater.from(parent.context))
root.updateLayoutParams<MarginLayoutParams> {
this.topMargin = this@ReminderContentHandler.topMargin
}
initView()
return root
}
protected abstract fun createView(inflater: LayoutInflater): View
protected abstract fun initView()
open fun dismissPop() = Unit
}
class SmsReminderUnableHandler(topMargin: Int, parent: ViewGroup, listener: OnReserveSuccessListener) :
ReminderContentHandler(topMargin, parent, listener) {
private lateinit var binding: LayoutReserveSmsReminderUnableBinding
override fun createView(inflater: LayoutInflater): View {
return LayoutReserveSmsReminderUnableBinding.inflate(inflater, parent, false)
.also {
binding = it
}.root
}
override fun initView() {
binding.vSmsAdd.setOnClickListener {
listener.updateSmsReminder(true)
}
}
}
class WechatReminderUnableHandler(topMargin: Int, parent: ViewGroup, listener: OnReserveSuccessListener) :
ReminderContentHandler(topMargin, parent, listener) {
private lateinit var binding: LayoutReserveWechatReminderUnableBinding
override fun createView(inflater: LayoutInflater): View {
return LayoutReserveWechatReminderUnableBinding.inflate(inflater, parent, false)
.also {
binding = it
}.root
}
override fun initView() {
binding.vWechatAdd.setOnClickListener {
listener.updateWechatReminder()
}
}
}
class SmsReminderEnableHandler(
private val smsConfig: ReserveReminderEntity.SmsConfig,
topMargin: Int,
parent: ViewGroup, listener:
OnReserveSuccessListener
) :
ReminderContentHandler(topMargin, parent, listener) {
private lateinit var binding: LayoutReserveSmsReminderEnableBinding
override val hasPopShowing: Boolean
get() = editBindPhoneInfoPop.isShowing
override fun dismissPop() {
if (hasPopShowing) {
editBindPhoneInfoPop.dismiss()
}
}
private val editBindPhoneInfoPop by lazy {
EditBindPhoneInfoPop.create(parent.context, smsConfig.mobileValidated, listener)
}
override fun createView(inflater: LayoutInflater) =
LayoutReserveSmsReminderEnableBinding.inflate(inflater, parent, false)
.also {
binding = it
}.root
override fun initView() {
binding.tvPhone.text = smsConfig.mobile
binding.vSmsEdit.setOnClickListener {
editBindPhoneInfoPop.showAsDropDown(
binding.ivSmsEdit,
(-104).dp,
0,
)
}
}
}
class WechatReminderEnableHandler(
private val nickName: String,
topMargin: Int,
parent: ViewGroup,
listener: OnReserveSuccessListener
) :
ReminderContentHandler(topMargin, parent, listener) {
private lateinit var binding: LayoutReserveWechatReminderEnableBinding
private val editWechatPop by lazy {
EditBindWechatPop.create(parent.context, listener)
}
override fun createView(inflater: LayoutInflater) =
LayoutReserveWechatReminderEnableBinding.inflate(inflater, parent, false)
.also {
binding = it
}.root
override fun initView() {
binding.tvWechat.text = nickName
binding.vModifyWechat.setOnClickListener {
editWechatPop.showAsDropDown(
binding.ivModifyWechat,
(-104).dp,
0
)
}
}
}
class OnlyWechatReminderUnableHandler(topMargin: Int, parent: ViewGroup, listener: OnReserveSuccessListener) :
ReminderContentHandler(topMargin, parent, listener) {
private lateinit var binding: LayoutReserveOnlyWechatUnableBinding
override fun createView(inflater: LayoutInflater) =
LayoutReserveOnlyWechatUnableBinding.inflate(inflater, parent, false)
.also {
binding = it
}.root
override fun initView() {
binding.vSubmitBackground.setOnClickListener {
listener.updateWechatReminder()
}
}
}
}
interface OnReserveSuccessListener {
fun updateSmsReminder(isEnable: Boolean)
fun updateWechatReminder()
fun changePhoneNumber()
fun verifyPhoneNumber()
fun changeWechatBinding()
}

View File

@ -1,63 +0,0 @@
package com.gh.common.dialog
import android.app.Dialog
import android.content.Context
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import com.gh.gamecenter.common.base.fragment.BaseDialogFragment
import com.gh.gamecenter.core.utils.CurrentActivityHolder
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.databinding.DialogWechatBindingConflictBinding
class WechatBindingConflictDialogFragment : BaseDialogFragment() {
private lateinit var binding: DialogWechatBindingConflictBinding
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return super.onCreateDialog(savedInstanceState).apply {
setCanceledOnTouchOutside(true)
}
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return DialogWechatBindingConflictBinding.inflate(inflater, container, false)
.also {
binding = it
}.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
binding.tvIKnow.setOnClickListener {
dismiss()
}
}
override fun onStart() {
super.onStart()
dialog?.window?.let {
it.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
val params = it.attributes
params.width = DisplayUtils.dip2px(300F)
it.attributes = params
}
}
companion object {
fun show(context: Context) {
if (context is AppCompatActivity) {
context.supportFragmentManager
} else {
(CurrentActivityHolder.getCurrentActivity() as? AppCompatActivity)?.supportFragmentManager
}?.let {
WechatBindingConflictDialogFragment().show(it, WechatBindingConflictDialogFragment::class.java.name)
}
}
}
}

View File

@ -1,125 +0,0 @@
package com.gh.common.dialog
import android.app.Dialog
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.graphics.Color
import android.graphics.drawable.ColorDrawable
import android.os.Bundle
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import androidx.appcompat.app.AppCompatActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.fragment.BaseDialogFragment
import com.gh.gamecenter.common.entity.ErrorEntity
import com.gh.gamecenter.core.utils.CurrentActivityHolder
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.databinding.DialogWechatBindingFailedBinding
import com.gh.gamecenter.login.user.UserRepository
import com.lightgame.utils.Utils
class WechatBindingFailedDialogFragment : BaseDialogFragment() {
private lateinit var binding: DialogWechatBindingFailedBinding
private var currentUserId: String? = null
private lateinit var userConflict: ErrorEntity.Data.UserConflict
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
userConflict = arguments?.getParcelable(KEY_USER_CONFLICT) ?: ErrorEntity.Data.UserConflict()
}
override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
return super.onCreateDialog(savedInstanceState).apply {
setCanceledOnTouchOutside(true)
}
}
override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
return DialogWechatBindingFailedBinding.inflate(inflater, container, false)
.also {
binding = it
}.root
}
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
super.onViewCreated(view, savedInstanceState)
UserRepository.getInstance().loginUserInfo.observe(viewLifecycleOwner) {
currentUserId = it.data.getShortUserId()
binding.tvCurrentName.text = it.data.name
binding.ivCurrentAvatar.displayAvatar(it.data.icon)
binding.tvUserId.text = getString(R.string.user_id, currentUserId)
}
binding.tvConflictName.text = userConflict.name
binding.ivConflictAvatar.displayAvatar(userConflict.icon)
binding.tvConflictUserId.text = getString(R.string.user_id, userConflict.seq)
binding.tvConflictProblem.setOnClickListener {
dismiss()
WechatBindingConflictDialogFragment.show(requireContext())
}
binding.tvIKnow.setOnClickListener {
dismiss()
}
binding.tvUserId.setOnLongClickListener {
currentUserId?.let {
copyTextToClipboard(it)
true
} ?: false
}
binding.tvConflictUserId.setOnLongClickListener {
copyTextToClipboard(userConflict.id)
true
}
}
private fun copyTextToClipboard(text: String) {
val clipboardManager = context?.getSystemService(Context.CLIPBOARD_SERVICE) as? ClipboardManager
if (clipboardManager != null) {
val clip = ClipData.newPlainText(COPY_ID_TEXT, text)
clipboardManager.setPrimaryClip(clip)
Utils.toast(requireContext(), R.string.copy_user_id_successfully)
}
}
override fun onStart() {
super.onStart()
dialog?.window?.let {
it.setBackgroundDrawable(ColorDrawable(Color.TRANSPARENT))
val params = it.attributes
params.width = DisplayUtils.dip2px(300F)
it.attributes = params
}
}
companion object {
private const val COPY_ID_TEXT = "user_id"
private const val KEY_USER_CONFLICT = "key_user_conflict"
fun show(context: Context, userConflict: ErrorEntity.Data.UserConflict?) {
if (context is AppCompatActivity) {
context.supportFragmentManager
} else {
(CurrentActivityHolder.getCurrentActivity() as? AppCompatActivity)?.supportFragmentManager
}?.let {
val fragment = WechatBindingFailedDialogFragment().apply {
arguments = Bundle().apply {
putParcelable(KEY_USER_CONFLICT, userConflict)
}
}
fragment.show(it, WechatBindingFailedDialogFragment::class.java.name)
}
}
}
}

View File

@ -6,7 +6,6 @@ import androidx.recyclerview.widget.LinearLayoutManager
import androidx.recyclerview.widget.RecyclerView
import androidx.recyclerview.widget.RecyclerView.LayoutManager
import androidx.recyclerview.widget.StaggeredGridLayoutManager
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.feature.exposure.ExposureEvent
import io.reactivex.functions.Consumer
@ -17,9 +16,8 @@ class ExposureListener(var fragment: Fragment, var exposable: IExposable) : Recy
val throttleBus: ExposureThrottleBus by lazy {
ExposureThrottleBus(
{ commitExposure(it) },
Consumer(Throwable::printStackTrace),
{ commitWXCPMExposure(it) }
Consumer { commitExposure(it) },
Consumer(Throwable::printStackTrace)
)
}
var layoutManager: LayoutManager? = null
@ -95,32 +93,4 @@ class ExposureListener(var fragment: Fragment, var exposable: IExposable) : Recy
ExposureManager.log(eventList)
}
/**
* 微信小游戏CPM曝光事件接口上报由于普通曝光事件的上报通道存在节流特性不符合CPM接口对于数据上报的实时性和准确性的要求所以使用额外的通道进行上报
*/
private fun commitWXCPMExposure(visibleState: ExposureThrottleBus.VisibleState) {
val eventList = arrayListOf<ExposureEvent>()
for (pos in visibleState.firstVisiblePosition..visibleState.lastVisiblePosition) {
try {
exposable.getEventByPosition(pos)?.let {
if (it.payload.miniGameType == Constants.WECHAT_MINI_GAME_CPM) {
eventList.add(it)
}
}
exposable.getEventListByPosition(pos)?.let { list ->
list.forEach {
if (it.payload.miniGameType == Constants.WECHAT_MINI_GAME_CPM) {
eventList.add(it)
}
}
}
} catch (ignore: Exception) {
// Just ignore the error.
}
}
ExposureManager.logCPM(eventList)
}
}

View File

@ -1,15 +1,13 @@
package com.gh.common.exposure
import com.aliyun.sls.android.producer.Log
import com.gh.gamecenter.BuildConfig
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.loghub.TLogHubHelper
import com.gh.gamecenter.common.loghub.LoghubHelper
import com.gh.gamecenter.common.utils.FixedSizeLinkedHashSet
import com.gh.gamecenter.common.utils.toJson
import com.gh.gamecenter.core.AppExecutor
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.feature.minigame.wechat.WGameSubjectCPMListReportHelper
import com.lightgame.utils.Utils
import com.volcengine.model.tls.LogItem
/**
* A handful tool for committing logs to aliyun loghub.
@ -34,9 +32,6 @@ object ExposureManager {
*/
fun log(event: ExposureEvent) {
AppExecutor.logExecutor.execute {
if (event.payload.miniGameType == Constants.WECHAT_MINI_GAME_CPM) {
WGameSubjectCPMListReportHelper.reportExposure(event)
}
if (!exposureCache.contains(event.id)) {
exposureSet.add(event)
exposureCache.add(event.id)
@ -63,17 +58,6 @@ object ExposureManager {
}
}
/**
* Log a wechat mini game cpm collection of exposure event.
*/
fun logCPM(eventList: List<ExposureEvent>) {
AppExecutor.logExecutor.execute {
if (eventList.isNotEmpty()) {
WGameSubjectCPMListReportHelper.reportExposure(eventList.toSet())
}
}
}
/**
* @param forcedUpload Ignore all restrictions.
*/
@ -94,20 +78,19 @@ object ExposureManager {
private fun uploadExposures(eventSet: HashSet<ExposureEvent>, forced: Boolean) {
eventSet.forEach {
TLogHubHelper.sendLog(buildLog(it), LOG_STORE)
// LoghubHelper.uploadLog(buildLog(it), LOG_STORE, forced)
LoghubHelper.uploadLog(buildLog(it), LOG_STORE, forced)
// it.recycle()
}
}
private fun buildLog(event: ExposureEvent) = LogItem(System.currentTimeMillis()).apply {
addContent("__id", event.id)
addContent("payload", event.payload.toJson())
addContent("event", event.event.toString())
addContent("source", eliminateMultipleBrackets(event.source.toJson()))
addContent("meta", event.meta.toJson())
addContent("real_millisecond", event.timeInMillisecond.toString())
addContent(
private fun buildLog(event: ExposureEvent) = Log().apply {
putContent("id", event.id)
putContent("payload", event.payload.toJson())
putContent("event", event.event.toString())
putContent("source", eliminateMultipleBrackets(event.source.toJson()))
putContent("meta", event.meta.toJson())
putContent("real_millisecond", event.timeInMillisecond.toString())
putContent(
"e-traces", if (event.eTrace != null) {
eliminateMultipleBrackets(event.eTrace?.toJson() ?: "")
} else ""

View File

@ -3,20 +3,16 @@ package com.gh.common.exposure
import io.reactivex.disposables.CompositeDisposable
import io.reactivex.functions.Consumer
import io.reactivex.schedulers.Schedulers
import io.reactivex.subjects.BehaviorSubject
import io.reactivex.subjects.PublishSubject
import java.util.concurrent.TimeUnit
class ExposureThrottleBus(
var onSuccess: Consumer<VisibleState>,
var onError: Consumer<Throwable>,
onPreSuccess: Consumer<VisibleState>
) {
class ExposureThrottleBus(var onSuccess: Consumer<VisibleState>, var onError: Consumer<Throwable>) {
companion object {
private const val THRESHOLD_TIME = 300L
}
private val mPublishSubject: BehaviorSubject<VisibleState> = BehaviorSubject.create()
private val mPublishSubject: PublishSubject<VisibleState> = PublishSubject.create()
private val mCompositeDisposable: CompositeDisposable = CompositeDisposable()
init {
@ -28,7 +24,6 @@ class ExposureThrottleBus(
*/
val disposable = mPublishSubject
.distinctUntilChanged()
.doOnNext(onPreSuccess)
.throttleWithTimeout(THRESHOLD_TIME, TimeUnit.MILLISECONDS)
.subscribeOn(Schedulers.io())
.subscribe(onSuccess, onError)

View File

@ -27,7 +27,7 @@ object ExposureUtils {
): ExposureEvent {
val gameEntity = entity.copy()
gameEntity.id = if (entity.id.contains(DownloadEntity.GAME_ID_DIVIDER)) {
entity.id.split(DownloadEntity.GAME_ID_DIVIDER).toTypedArray().firstOrNull() ?: ""
entity.id.split(DownloadEntity.GAME_ID_DIVIDER).toTypedArray()[0]
} else {
entity.id
}
@ -53,6 +53,7 @@ object ExposureUtils {
return exposureEvent
}
@JvmStatic
fun logADownloadCompleteExposureEvent(
entity: GameEntity,
platform: String?,
@ -60,7 +61,6 @@ object ExposureUtils {
speed: Long,
host: String? = "unknown",
path: String? = "unknown",
redirectedUrlList: String? = "unknown",
downloadType: DownloadType
): ExposureEvent? {
val gameEntity = entity.copy()
@ -88,7 +88,6 @@ object ExposureUtils {
exposureEvent.payload.host = host
exposureEvent.payload.path = path
exposureEvent.payload.speed = speed
exposureEvent.payload.redirectedUrlList = redirectedUrlList
ExposureManager.log(exposureEvent)
ExposureManager.commitSavedExposureEvents(forcedUpload = true)

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 = 14,
version = 13,
exportSchema = false
)
@TypeConverters(
@ -41,8 +41,7 @@ import com.halo.assistant.HaloApp
SimpleGameListConverter::class,
TagInfoListConverter::class,
ActivityLabelListConverter::class,
IconFloatConverter::class,
SectionConverter::class
IconFloatConverter::class
)
abstract class HistoryDatabase : RoomDatabase() {
@ -144,14 +143,6 @@ abstract class HistoryDatabase : RoomDatabase() {
}
}
val MIGRATION_13_14: Migration = object : Migration(13, 14) {
override fun migrate(database: SupportSQLiteDatabase) {
database.execSQL("Alter TABLE ArticleEntity add type TEXT NOT NULL DEFAULT 'community_article'")
database.execSQL("Alter TABLE ArticleEntity add sections TEXT NOT NULL DEFAULT ''")
database.execSQL("Alter TABLE ArticleEntity add tagActivityName TEXT NOT NULL DEFAULT ''")
}
}
val instance by lazy {
Room.databaseBuilder(
HaloApp.getInstance().application,
@ -169,7 +160,6 @@ abstract class HistoryDatabase : RoomDatabase() {
.addMigrations(MIGRATION_10_11)
.addMigrations(MIGRATION_11_12)
.addMigrations(MIGRATION_12_13)
.addMigrations(MIGRATION_13_14)
.build()
}
}

View File

@ -6,7 +6,11 @@ import com.gh.gamecenter.common.utils.removeVideoContent
import com.gh.gamecenter.common.utils.tryCatchInRelease
import com.gh.gamecenter.core.runOnIoThread
import com.gh.gamecenter.entity.*
import com.gh.gamecenter.feature.entity.*
import com.gh.gamecenter.feature.entity.AnswerEntity
import com.gh.gamecenter.feature.entity.ArticleEntity
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.entity.NewsEntity
import com.gh.gamecenter.feature.entity.User
import com.gh.gamecenter.qa.entity.AnswerDetailEntity
import com.gh.gamecenter.qa.entity.ArticleDetailEntity
@ -104,7 +108,7 @@ object HistoryHelper {
fun deleteArticleEntity(articleId: String) {
runOnIoThread {
tryCatchInRelease {
HistoryDatabase.instance.articleDao().deleteArticle(ArticleEntity(_id = articleId))
HistoryDatabase.instance.articleDao().deleteArticle(ArticleEntity(id = articleId))
}
}
}
@ -165,9 +169,6 @@ object HistoryHelper {
articleEntity.images = articleDetailEntity.images
articleEntity.imagesInfo = articleDetailEntity.imagesInfo
articleEntity.videos = articleDetailEntity.videos
articleEntity.tagActivityName = articleDetailEntity.tagActivityName
articleEntity.sections = articleDetailEntity.sections ?: emptyList()
articleEntity.type = "community_article"
return articleEntity
}

View File

@ -1,10 +0,0 @@
package com.gh.common.iinterface
import com.gh.gamecenter.entity.MultiTabNav
interface IMultiTab {
fun provideMultiTabId(): String
fun provideMultiTabName(): String
fun provideCurrentTabEntity(): MultiTabNav.LinkMultiTabNav?
fun provideLastSelectedPosition(): Int
}

View File

@ -1,10 +0,0 @@
package com.gh.common.iinterface
import com.gh.gamecenter.entity.BottomTab
interface ISearchToolbarTab {
fun onScrollChanged(totalHeight: Int, offset: Int, isDarkModeChanged: Boolean)
fun changeAppBarColor(color: Int, pageId: String)
fun updateSearchStyle(searchStyle: BottomTab.SearchStyle)
fun getCurrentTabIndex(): Int?
}

View File

@ -1,6 +1,5 @@
package com.gh.common.iinterface
import com.gh.common.prioritychain.PullDownPushHandler
import com.gh.gamecenter.entity.PullDownPush
interface ISmartRefresh {
@ -8,5 +7,5 @@ interface ISmartRefresh {
fun finishTwoLevel(action: String)
fun finishRefresh()
fun popupPullDownPush(finishCallback: () -> Unit)
fun setPullDownPush(pullDownPush: PullDownPush?, pullDownPushHandler: PullDownPushHandler?)
fun setPullDownPush(pullDownPush: PullDownPush?)
}

View File

@ -1,5 +1,7 @@
package com.gh.common.iinterface
import android.view.View
interface ISmartRefreshContent {
/**
* 启用/关闭 页面滑动
@ -14,4 +16,6 @@ interface ISmartRefreshContent {
* @param isSwipeRefreshEnabled 是否启用
*/
fun setSwipeRefreshEnabled(isSwipeRefreshEnabled: Boolean)
fun provideSlideBackgroundView(): View?
}

View File

@ -1,44 +0,0 @@
package com.gh.common.pop
import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.core.view.updateLayoutParams
import com.gh.gamecenter.R
import com.gh.gamecenter.common.databinding.LayoutPopupContainerBinding
import com.gh.gamecenter.common.view.BugFixedPopupWindow
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.databinding.LayoutAddKaifuPopupItemBinding
class BatchManagementPop(
binding: LayoutPopupContainerBinding,
private val listener: OnBatchManagementListener
) :
CommonPopupWindow(binding) {
override val viewDataList: List<ViewData>
get() = listOf(
ViewData(R.string.enable_automatic_downloading_in_batches) {
listener.enableAutoDownload()
},
ViewData(R.string.batch_management) {
listener.batchManage()
}
)
companion object {
fun create(context: Context, listener: OnBatchManagementListener): BatchManagementPop {
val binding = LayoutPopupContainerBinding.inflate(LayoutInflater.from(context))
return BatchManagementPop(binding, listener).apply {
initView()
}
}
}
interface OnBatchManagementListener {
fun enableAutoDownload()
fun batchManage()
}
}

View File

@ -1,49 +0,0 @@
package com.gh.common.pop
import android.content.Context
import android.view.LayoutInflater
import com.gh.gamecenter.R
import com.gh.gamecenter.common.databinding.LayoutPopupContainerBinding
import com.gh.gamecenter.feature.entity.GameEntity
class CancelReservePop(
private val game: GameEntity,
binding: LayoutPopupContainerBinding,
private val listener: OnCancelReserveListener
) : CommonPopupWindow(binding) {
override val viewDataList: List<ViewData>
get() {
val list = arrayListOf<ViewData>()
if (game.wifiAutoDownloadEnable) {
list.add(ViewData(if (game.wifiAutoDownload) R.string.cancel_auto_download_with_wifi else R.string.enable_automatic_downloading_with_wifi) {
listener.enableAutoDownload(!game.wifiAutoDownload)
})
}
list.add(ViewData(R.string.cancel_reserve, listener::cancelReserve))
return list
}
companion object {
fun create(
game: GameEntity,
context: Context,
listener: OnCancelReserveListener
): CancelReservePop {
val inflater = LayoutInflater.from(context)
val binding = LayoutPopupContainerBinding.inflate(inflater)
return CancelReservePop(game, binding, listener).apply {
initView()
}
}
}
interface OnCancelReserveListener {
fun enableAutoDownload(isEnable: Boolean)
fun cancelReserve()
}
}

View File

@ -1,47 +0,0 @@
package com.gh.common.pop
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.core.view.updateLayoutParams
import com.gh.gamecenter.common.databinding.LayoutPopupContainerBinding
import com.gh.gamecenter.common.view.BugFixedPopupWindow
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.databinding.LayoutAddKaifuPopupBinding
import com.gh.gamecenter.databinding.LayoutAddKaifuPopupItemBinding
import com.gh.gamecenter.databinding.LayoutPopupOptionItemBinding
import com.gh.gamecenter.databinding.LayoutPopupReserveReminderOptionItemBinding
abstract class CommonPopupWindow(
private val binding: LayoutPopupContainerBinding,
) : BugFixedPopupWindow(binding.root, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT) {
private val inflater = LayoutInflater.from(binding.root.context)
abstract val viewDataList: List<ViewData>
fun initView() {
isFocusable = true
binding.container.updateLayoutParams<ViewGroup.LayoutParams> {
width = DisplayUtils.dip2px(128F)
}
viewDataList.forEach {
addItemView(it.textResId, it.click)
}
}
private fun addItemView(textResId: Int, click: () -> Unit) =
LayoutPopupReserveReminderOptionItemBinding.inflate(inflater, binding.container, false)
.also {
it.hintText.setText(textResId)
binding.container.addView(it.root)
it.root.setOnClickListener {
dismiss()
click()
}
}.root
data class ViewData(
val textResId: Int,
val click: () -> Unit
)
}

View File

@ -1,70 +0,0 @@
package com.gh.common.pop
import android.content.Context
import android.view.LayoutInflater
import android.view.ViewGroup
import androidx.core.view.updateLayoutParams
import com.gh.common.dialog.OnReserveSuccessListener
import com.gh.gamecenter.R
import com.gh.gamecenter.common.databinding.LayoutPopupContainerBinding
import com.gh.gamecenter.common.view.BugFixedPopupWindow
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.databinding.LayoutAddKaifuPopupItemBinding
class EditBindPhoneInfoPop(
private val hasValidated: Boolean,
private val binding: LayoutPopupContainerBinding,
private val listener: OnReserveSuccessListener
) : BugFixedPopupWindow(binding.root, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT) {
private val context
get() = binding.root.context
init {
initView()
}
private fun initView() {
isOutsideTouchable = false
isFocusable = true
binding.container.updateLayoutParams<ViewGroup.LayoutParams> {
width = DisplayUtils.dip2px(128F)
}
val inflater = LayoutInflater.from(context)
fun createItemView(textResId: Int) =
LayoutAddKaifuPopupItemBinding.inflate(inflater, binding.container, false)
.also {
it.hintText.setText(textResId)
binding.container.addView(it.root)
}.root
val tvChangePhoneNumber = createItemView(R.string.change_phone_number)
if(!hasValidated){
val tvVerifyPhoneNumber = createItemView(R.string.verify_phone_number)
tvVerifyPhoneNumber.setOnClickListener {
dismiss()
listener.verifyPhoneNumber()
}
}
val tvTurnOffSmsReminder = createItemView(R.string.turn_off_sms_reminders)
tvChangePhoneNumber.setOnClickListener {
dismiss()
listener.changePhoneNumber()
}
tvTurnOffSmsReminder.setOnClickListener {
dismiss()
listener.updateSmsReminder(false)
}
}
companion object {
fun create(context: Context, hasValidated: Boolean, listener: OnReserveSuccessListener): EditBindPhoneInfoPop {
val binding = LayoutPopupContainerBinding.inflate(LayoutInflater.from(context))
return EditBindPhoneInfoPop(hasValidated, binding, listener)
}
}
}

View File

@ -1,26 +0,0 @@
package com.gh.common.pop
import android.content.Context
import android.view.LayoutInflater
import com.gh.common.dialog.OnReserveSuccessListener
import com.gh.gamecenter.R
import com.gh.gamecenter.common.databinding.LayoutPopupContainerBinding
class EditBindWechatPop(
binding: LayoutPopupContainerBinding,
private val listener: OnReserveSuccessListener
) : CommonPopupWindow(binding) {
override val viewDataList: List<ViewData>
get() = listOf(
ViewData(R.string.change_the_wechat_binding, listener::changeWechatBinding)
)
companion object {
fun create(context: Context, listener: OnReserveSuccessListener): EditBindWechatPop {
val inflater = LayoutInflater.from(context)
return EditBindWechatPop(LayoutPopupContainerBinding.inflate(inflater), listener).apply { initView() }
}
}
}

View File

@ -1,69 +0,0 @@
package com.gh.common.pop
import android.content.Context
import android.graphics.Color
import android.text.SpannableString
import android.text.TextPaint
import android.text.method.LinkMovementMethod
import android.text.style.ClickableSpan
import android.text.style.ForegroundColorSpan
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import androidx.core.text.set
import com.gh.common.dialog.OnReserveSuccessListener
import com.gh.gamecenter.R
import com.gh.gamecenter.common.utils.toColor
import com.gh.gamecenter.common.utils.toResString
import com.gh.gamecenter.common.view.BugFixedPopupWindow
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.databinding.PopRealNameTipsBinding
import com.halo.assistant.fragment.reserve.OnReserveReminderListener
class RealNameTipsPop(
private val binding: PopRealNameTipsBinding,
private val listener: OnReserveReminderListener
) :
BugFixedPopupWindow(binding.root, ViewGroup.LayoutParams.WRAP_CONTENT, ViewGroup.LayoutParams.WRAP_CONTENT) {
private val context: Context
get() = binding.root.context
init {
initView()
}
private fun initView() {
val text = R.string.reserve_real_name_description.toResString()
val spannableString = SpannableString(text)
val clickSpan = object : ClickableSpan() {
override fun updateDrawState(ds: TextPaint) {
ds.bgColor = Color.TRANSPARENT
ds.setColor(com.gh.gamecenter.common.R.color.text_theme.toColor(context))
}
override fun onClick(widget: View) {
dismiss()
listener.realName()
}
}
spannableString.set(start = text.length - 6, end = text.length, span = clickSpan)
binding.tvRealNameDescription.text = spannableString
binding.tvRealNameDescription.movementMethod = LinkMovementMethod.getInstance()
binding.tvRealNameDescription.setHighlightColor(Color.TRANSPARENT)
}
companion object {
@JvmStatic
fun create(context: Context, listener: OnReserveReminderListener): RealNameTipsPop {
val pop = RealNameTipsPop(PopRealNameTipsBinding.inflate(LayoutInflater.from(context)), listener)
pop.isFocusable = true
pop.isOutsideTouchable = false
return pop
}
}
}

View File

@ -1,95 +0,0 @@
package com.gh.common.pop
import android.content.Context
import android.view.Gravity
import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.CompoundButton
import androidx.appcompat.app.AppCompatActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.common.utils.dip2px
import com.gh.gamecenter.common.view.BugFixedPopupWindow
import com.gh.gamecenter.databinding.PopReserveAllSelectBinding
import com.gh.gamecenter.mygame.MyReservationFragment
class ReserveAllSelectPop(
val binding: PopReserveAllSelectBinding,
private val listener: OnReserveAllSelectListener
) : BugFixedPopupWindow(binding.root, ViewGroup.LayoutParams.MATCH_PARENT, 56F.dip2px()) {
private var pageStatus: MyReservationFragment.ReservePageState =
MyReservationFragment.ReservePageState.EnableAutoDownload
private val onCheckedChangeListener = { _: CompoundButton, isChecked: Boolean ->
val count = listener.selectAll(isChecked)
updateSelectedCount(count)
}
init {
isOutsideTouchable = false
binding.cbAll.setOnCheckedChangeListener(onCheckedChangeListener)
binding.tvSubmit.setOnClickListener {
listener.submit()
}
}
fun show(state: MyReservationFragment.ReservePageState, context: Context) {
enableSubmit(false)
binding.tvSubmit.setText(
if (state == MyReservationFragment.ReservePageState.EnableAutoDownload) {
R.string.enable_automatic_downloading_with_wifi
} else {
R.string.cancel_reserve
}
)
// 清空上一次的状态
pageStatus = state
updateSelectedCount(0)
if (!isShowing) {
showAtLocation((context as AppCompatActivity).window.decorView, Gravity.BOTTOM, 0, 0)
}
}
fun updateSelectedCount(count: Int) {
if (count == 0) {
enableSubmit(false)
binding.cbAll.setOnCheckedChangeListener(null)
binding.cbAll.isChecked = false
binding.cbAll.setOnCheckedChangeListener(onCheckedChangeListener)
} else {
enableSubmit(true)
binding.tvNumber.text = binding.root.context.getString(R.string.count_with_parentheses, "$count")
}
}
private fun enableSubmit(isEnable: Boolean) {
binding.tvSubmit.isEnabled = isEnable
if (isEnable) {
binding.tvSubmit.alpha = 1F
} else {
binding.tvSubmit.alpha = 0.4F
binding.tvNumber.setText(null)
}
}
companion object {
fun create(context: Context, listener: OnReserveAllSelectListener): ReserveAllSelectPop {
val inflater = LayoutInflater.from(context)
return ReserveAllSelectPop(PopReserveAllSelectBinding.inflate(inflater), listener)
}
}
interface OnReserveAllSelectListener {
fun selectAll(isChecked: Boolean): Int
fun submit()
}
}

View File

@ -1,12 +1,13 @@
package com.gh.common.prioritychain
import android.app.Activity
import android.os.Handler
import android.view.Gravity
import android.view.LayoutInflater
import android.widget.FrameLayout
import com.gh.common.util.NewFlatLogUtils
import com.gh.gamecenter.GameDetailActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.common.base.fragment.BaseFragment
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.view.BugFixedPopupWindow
import com.gh.gamecenter.core.utils.DisplayUtils
@ -18,7 +19,7 @@ import com.gh.gamecenter.wrapper.MainWrapperViewModel
class AccelerateNotificationHandler(priority: Int) : PriorityChainHandler(priority) {
private var mActivity: Activity? = null
private var mHandler: Handler? = null
private var mBaseHandler: BaseFragment.BaseHandler? = null
private var mGameList: List<GameEntity>? = null
private var mViewModel: MainWrapperViewModel? = null
@ -27,13 +28,13 @@ class AccelerateNotificationHandler(priority: Int) : PriorityChainHandler(priori
*/
fun doPreProcess(
activity: Activity,
handler: Handler,
baseHandler: BaseFragment.BaseHandler,
gameEntityList: List<GameEntity>?,
viewModel: MainWrapperViewModel
) {
mActivity = activity
mGameList = gameEntityList
mHandler = handler
mBaseHandler = baseHandler
mViewModel = viewModel
if (getStatus() == STATUS_PENDING) {
@ -58,7 +59,7 @@ class AccelerateNotificationHandler(priority: Int) : PriorityChainHandler(priori
val accelerateSet =
HashSet(SPUtils.getStringSet(Constants.SP_ACCELERATE_NOTIFICATION_POP_UP_SET))
if (!mGameList.isNullOrEmpty() && !accelerateSet.contains(mGameList!![0].messageId)) {
showAccelerateNotificationPopupWindow(mActivity!!, mViewModel, mHandler, mGameList!![0]) {
showAccelerateNotificationPopupWindow(mActivity!!, mViewModel, mBaseHandler, mGameList!![0]) {
processNext()
}
accelerateSet.add(mGameList!![0].messageId)
@ -81,7 +82,7 @@ class AccelerateNotificationHandler(priority: Int) : PriorityChainHandler(priori
fun showAccelerateNotificationPopupWindow(
activity: Activity,
viewModel: MainWrapperViewModel?,
handler: Handler?,
baseHandler: BaseFragment.BaseHandler?,
gameEntity: GameEntity?,
dismissCallback: (() -> Unit)?
) {
@ -120,7 +121,7 @@ class AccelerateNotificationHandler(priority: Int) : PriorityChainHandler(priori
isTouchable = true
isFocusable = true
isOutsideTouchable = true
animationStyle = com.gh.gamecenter.common.R.style.popup_window_ease_in_and_out_anim_style
animationStyle = R.style.popup_window_ease_in_and_out_anim_style
showAtLocation(
activity.window.decorView,
Gravity.TOP,
@ -130,7 +131,7 @@ class AccelerateNotificationHandler(priority: Int) : PriorityChainHandler(priori
setOnDismissListener {
dismissCallback?.invoke()
}
handler?.postDelayed({ dismiss() }, 5000)
baseHandler?.postDelayed({ dismiss() }, 5000)
}
}
}

View File

@ -1,168 +0,0 @@
package com.gh.common.prioritychain
import android.app.Activity
import android.os.Handler
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.PopupWindow
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.view.updateLayoutParams
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.utils.dip2px
import com.gh.gamecenter.common.view.BugFixedPopupWindow
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.databinding.PopupBottomTabGuideBinding
import com.gh.gamecenter.entity.BottomTab
class BottomTabGuideHandler(priority: Int): PriorityChainHandler(priority) {
private var mActivity: Activity? = null
private var mHandler: Handler? = null
private var mViewPager: ViewGroup? = null
private var mGuide: BottomTab.Guide? = null
private var mTriangleTransX = 0F
private var mGuideTransX = 0F
private var mRestWidth = 0F
private var mIsCenterPosition = false
private var mIsRightPosition = false
private var mPopupWindow: PopupWindow? = null
fun doPreProcess(
shouldShow: Boolean,
activity: Activity? = null,
handler: Handler? = null,
viewPager: ViewGroup? = null,
guide: BottomTab.Guide? = null,
triangleTransX: Float = 0F,
guideTransX: Float = 0F,
restWidth: Float = 0F,
isCenterPosition: Boolean = false,
isRightPosition: Boolean = false
) {
mActivity = activity
mHandler = handler
mViewPager = viewPager
mGuide = guide
mTriangleTransX = triangleTransX
mGuideTransX = guideTransX
mRestWidth = restWidth
mIsCenterPosition = isCenterPosition
mIsRightPosition = isRightPosition
if (getStatus() == STATUS_PENDING) {
if (shouldShow) {
updateStatus(STATUS_VALID)
process()
} else {
processNext()
}
} else {
if (shouldShow) {
updateStatus(STATUS_VALID)
} else {
updateStatus(STATUS_INVALID)
}
}
}
override fun onProcess(): Boolean {
when (getStatus()) {
STATUS_VALID -> {
if (mGuide == null || mActivity == null || mViewPager == null) {
processNext()
return false
}
val guideSet = HashSet(SPUtils.getStringSet(Constants.SP_BOTTOM_TAB_GUIDE_SET))
if (!guideSet.contains(mGuide?.bottomTabId + mGuide?.text)) {
mPopupWindow = showBottomTabPopupWindow(
mActivity!!,
mHandler,
mViewPager!!,
mGuide!!,
mTriangleTransX,
mGuideTransX,
mRestWidth,
mIsCenterPosition,
mIsRightPosition
) {
processNext()
}
guideSet.add(mGuide?.bottomTabId + mGuide?.text)
SPUtils.setStringSet(Constants.SP_BOTTOM_TAB_GUIDE_SET, guideSet)
return true
} else {
processNext()
}
}
STATUS_INVALID -> {
processNext()
}
}
return false
}
fun dismiss() {
if (mPopupWindow?.isShowing == true) {
mPopupWindow?.dismiss()
}
}
companion object {
const val KEY_BOTTOM_TAB_GUIDE_AUTO_DISMISS = 100
private const val AUTO_DISMISS_DELAY_TIME = 5000L
fun showBottomTabPopupWindow(
activity: Activity,
handler: Handler?,
viewPager: ViewGroup,
guide: BottomTab.Guide,
triangleTransX: Float,
guideTransX: Float,
restWidth: Float,
isCenterPosition: Boolean,
isRightPosition: Boolean,
dismissCallback: (() -> Unit)?
): PopupWindow {
val binding = PopupBottomTabGuideBinding.inflate(LayoutInflater.from(activity))
binding.guideTv.text = guide.text
binding.guideTriangleIv.translationX = triangleTransX
binding.guideTv.translationX = guideTransX
binding.guideIconIv.translationX = guideTransX
binding.guideTv.updateLayoutParams<ConstraintLayout.LayoutParams> {
horizontalBias = if (isCenterPosition) 0.5F else if (isRightPosition) 1F else 0F
}
val popupWindow = BugFixedPopupWindow(
binding.root,
ConstraintLayout.LayoutParams.MATCH_PARENT,
ConstraintLayout.LayoutParams.WRAP_CONTENT
)
popupWindow.contentView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED)
val measureWidth = popupWindow.contentView.measuredWidth
val measureHeight = popupWindow.contentView.measuredHeight
if (measureWidth > restWidth) {
binding.guideTv.translationX = 0F
binding.guideIconIv.translationX = 0F
}
return popupWindow.apply {
isFocusable = false
isOutsideTouchable = false
animationStyle = com.gh.gamecenter.common.R.style.popup_window_ease_in_and_out_anim_style
setOnDismissListener {
dismissCallback?.invoke()
}
handler?.post {
if (!activity.isFinishing) {
showAsDropDown(viewPager, 0, 8F.dip2px() - measureHeight)
}
handler.sendEmptyMessageDelayed(KEY_BOTTOM_TAB_GUIDE_AUTO_DISMISS, AUTO_DISMISS_DELAY_TIME)
}
}
}
}
}

View File

@ -1,52 +0,0 @@
package com.gh.common.prioritychain
import android.content.Context
import android.view.LayoutInflater
import android.widget.FrameLayout
import com.airbnb.lottie.LottieAnimationView
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.databinding.LayoutCommunityHomeVideoGuideBinding
class CommunityHomeGuideHandler(
priority: Int,
private val context: Context,
private val decorView: FrameLayout?,
private val videoLottie: LottieAnimationView?
) : PriorityChainHandler(priority) {
init {
updateStatus(STATUS_VALID)
}
override fun onProcess(): Boolean {
return if (SPUtils.getBoolean(Constants.SP_SHOW_COMMUNITY_HOME_VIDEO_GUIDE, true)) {
showHomeVideoGuide(context, decorView, videoLottie)
processNext()
true
} else {
processNext()
false
}
}
companion object {
fun showHomeVideoGuide(context: Context, decorView: FrameLayout?, videoLottie: LottieAnimationView?) {
val guideLayoutBinding = LayoutCommunityHomeVideoGuideBinding.inflate(
LayoutInflater.from(context),
decorView,
true
)
guideLayoutBinding.root.setOnClickListener { view ->
decorView?.removeView(view)
SPUtils.setBoolean(Constants.SP_SHOW_COMMUNITY_HOME_VIDEO_GUIDE, false)
videoLottie?.playAnimation()
SPUtils.setLong(
Constants.SP_COMMUNITY_HOME_VIDEO_LOTTIE_LAST_PLAY_TIME,
System.currentTimeMillis()
)
}
}
}
}

View File

@ -2,7 +2,7 @@ package com.gh.common.prioritychain
import androidx.lifecycle.LiveData
import androidx.lifecycle.MutableLiveData
import com.gh.gamecenter.feature.entity.FloatingWindowEntity
import com.gh.gamecenter.floatingwindow.FloatingWindowEntity
import com.gh.gamecenter.livedata.Event
class CustomFloatingWindowHandler(priority: Int) : PriorityChainHandler(priority) {
@ -60,7 +60,7 @@ class CustomFloatingWindowHandler(priority: Int) : PriorityChainHandler(priority
when (getStatus()) {
STATUS_VALID -> {
_showFloatingAction.value = Event(data)
return true
processNext()
// floatingWindowProvider.showFloatingWindowOnly(
// mFragment!!,
// mRecyclerView!!,
@ -79,9 +79,4 @@ class CustomFloatingWindowHandler(priority: Int) : PriorityChainHandler(priority
return false
}
fun dismiss() {
if (getStatus() == STATUS_HANDLING || getStatus() == STATUS_VALID) {
processNext()
}
}
}

View File

@ -0,0 +1,89 @@
package com.gh.common.prioritychain
import androidx.recyclerview.widget.RecyclerView
import com.alibaba.android.arouter.launcher.ARouter
import com.gh.gamecenter.common.base.fragment.BaseLazyFragment
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.core.provider.IFloatingWindowProvider
import com.gh.gamecenter.feature.entity.WelcomeDialogEntity
import com.gh.gamecenter.floatingwindow.FloatingWindowEntity
import com.gh.gamecenter.fragment.WelcomeDialogFragment
import com.lightgame.utils.Utils
class FloatingWindowHandler(priority: Int) : PriorityChainHandler(priority) {
private var mFragment: BaseLazyFragment? = null
private var mRecyclerView: RecyclerView? = null
private var mWindowList: ArrayList<FloatingWindowEntity>? = null
fun setData(windowList: ArrayList<FloatingWindowEntity>?) {
mWindowList = windowList
if (mFragment != null) {
doPreProcess()
}
}
fun setView(
fragment: BaseLazyFragment,
recyclerView: RecyclerView
) {
mFragment = fragment
mRecyclerView = recyclerView
if (mWindowList != null) {
doPreProcess()
}
}
private fun doPreProcess() {
Utils.log(TAG, "FloatingWindowHandler preProcess windowSize is -> ${mWindowList?.size}")
if (getStatus() == STATUS_PENDING) {
if (!mWindowList.isNullOrEmpty()) {
updateStatus(STATUS_VALID)
process()
} else {
processNext()
}
} else {
if (!mWindowList.isNullOrEmpty()) {
updateStatus(STATUS_VALID)
} else {
updateStatus(STATUS_INVALID)
}
}
}
override fun onProcess(): Boolean {
when (getStatus()) {
STATUS_VALID -> {
val floatingWindowProvider =
ARouter.getInstance().build(RouteConsts.provider.floatingwindow)
.navigation() as? IFloatingWindowProvider<WelcomeDialogEntity>
// 强校验所有条件均通过才能显示
if (floatingWindowProvider == null || mFragment == null || mFragment?.isAdded == false || mRecyclerView == null) {
processNext()
return false
}
floatingWindowProvider.showFloatingWindowOnly(
mFragment!!,
mRecyclerView!!,
mWindowList!!,
) {
val welcomeDialog = WelcomeDialogFragment.getInstance(it, true, mFragment)
welcomeDialog.show(mFragment!!.childFragmentManager, "WelcomeDialog")
}
}
STATUS_INVALID -> {
processNext()
}
}
return false
}
}

View File

@ -5,35 +5,22 @@ import android.app.Activity
import android.app.Application.ActivityLifecycleCallbacks
import android.os.Bundle
import android.preference.PreferenceManager
import android.text.TextUtils
import androidx.annotation.WorkerThread
import androidx.fragment.app.FragmentActivity
import com.gh.common.iinterface.ISuperiorChain
import com.gh.common.util.CheckLoginUtils
import com.gh.common.util.PackageUtils
import com.gh.download.DownloadManager
import com.gh.gamecenter.SplashAdActivity
import com.gh.gamecenter.SplashScreenActivity
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.exposure.ExposureSource
import com.gh.gamecenter.common.entity.SimpleGameEntity
import com.gh.gamecenter.common.retrofit.BiResponse
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.core.AppExecutor
import com.gh.gamecenter.core.runOnIoThread
import com.gh.gamecenter.common.utils.debugOnly
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.core.utils.SPUtils.getBoolean
import com.gh.gamecenter.core.utils.ToastUtils
import com.gh.gamecenter.entity.DialogEntity
import com.gh.gamecenter.feature.entity.GameEntity
import com.gh.gamecenter.feature.entity.ReserveOnlineEntity
import com.gh.gamecenter.feature.entity.WelcomeDialogEntity
import com.gh.gamecenter.feature.exposure.ExposureEvent
import com.gh.gamecenter.hud.PendingInstallHUDHandler
import com.gh.gamecenter.hud.ResumeDownloadHudHandler
import com.gh.gamecenter.login.entity.UserInfoEntity
import com.gh.gamecenter.login.user.UserManager
import com.gh.gamecenter.retrofit.RetrofitManager
import com.halo.assistant.HaloApp
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
/**
@ -45,7 +32,6 @@ import io.reactivex.schedulers.Schedulers
object GlobalPriorityChainHelper : ISuperiorChain {
private val api = RetrofitManager.getInstance().api
private val newApi = RetrofitManager.getInstance().newApi
private var inferiorChain: PriorityChain? = null
private val mainChain: PriorityChain by lazy { PriorityChain { inferiorChain?.start() } }
@ -57,21 +43,18 @@ object GlobalPriorityChainHelper : ISuperiorChain {
return activity is FragmentActivity
&& !activity.isFinishing
&& activity !is SplashScreenActivity
&& activity !is SplashAdActivity
}
/**
* 预启动所有的优先级弹窗管理链
*/
fun preStart(withSpecialDelay: Boolean) {
fun preStart() {
val launchRedirectHandler = LaunchRedirectHandler(-101)
val updateDialogHandler = UpdateDialogHandler(-100)
val privacyPolicyDialogHandler = PrivacyPolicyDialogHandler(-99)
val notificationPermissionDialogHandler = NotificationPermissionDialogHandler(0)
val reserveDialogHandler = ReserveDialogHandler(1)
val welcomeDialogHandler = WelcomeDialogHandler(2)
val pendingInstallHandler = PendingInstallHUDHandler(3)
val resumeDownloadHandler = ResumeDownloadHudHandler(4)
mainChain.addHandler(launchRedirectHandler)
mainChain.addHandler(updateDialogHandler)
@ -79,18 +62,11 @@ object GlobalPriorityChainHelper : ISuperiorChain {
mainChain.addHandler(welcomeDialogHandler)
mainChain.addHandler(reserveDialogHandler)
mainChain.addHandler(notificationPermissionDialogHandler)
mainChain.addHandler(pendingInstallHandler)
mainChain.addHandler(resumeDownloadHandler)
launchRedirectHandler.doPreProcess()
updateDialogHandler.doPreProcess()
// 首次启动延迟 300ms保证请求首次启动时已经获取到了 GID 、 OAID 等标记
val requestDelay = if (withSpecialDelay) 300L else 0L
AppExecutor.uiExecutor.executeWithDelay({
requestOpeningDialogData(welcomeDialogHandler, privacyPolicyDialogHandler)
requestReserveDialogData(reserveDialogHandler)
}, requestDelay)
requestOpeningDialogData(welcomeDialogHandler, privacyPolicyDialogHandler)
requestReserveDialogData(reserveDialogHandler)
}
/**
@ -148,17 +124,6 @@ object GlobalPriorityChainHelper : ISuperiorChain {
mainChain.resume()
}
/**
* 添加新的 handler 到优先级弹窗管理链 (插队!)
*/
fun queueNewHandler(handler: PriorityChainHandler) {
if (mainChain.isHandlerQueueEmpty()) {
observeLifecycle()
}
mainChain.addHandler(handler)
}
/**
* 请求首页启动弹窗相关的数据并执行相关 handler 的 preProcess
*/
@ -226,7 +191,6 @@ object GlobalPriorityChainHelper : ISuperiorChain {
override fun onFailure(exception: Exception) {
privacyPolicyDialogHandler.doPreProcess(null)
welcomeDialogHandler.doPreProcess(null)
}
})
}
@ -234,7 +198,7 @@ object GlobalPriorityChainHelper : ISuperiorChain {
/**
* 请求预约弹窗相关的数据
*/
@SuppressLint("CheckResult")
private fun requestReserveDialogData(reserveDialogHandler: ReserveDialogHandler) {
// debugOnly {
// reserveDialogHandler.doPreProcess(arrayListOf(SimpleGameEntity(
@ -247,145 +211,23 @@ object GlobalPriorityChainHelper : ISuperiorChain {
// }
if (CheckLoginUtils.isLogin()) {
val isTeenagerMode = getBoolean(Constants.SP_TEENAGER_MODE)
loadReserveDialogOnlineData(isTeenagerMode, reserveDialogHandler)
api.getReserveDialog(UserManager.getInstance().userId)
.subscribeOn(Schedulers.io())
.observeOn(AndroidSchedulers.mainThread())
.subscribe(object : BiResponse<List<SimpleGameEntity>>() {
override fun onSuccess(data: List<SimpleGameEntity>) {
reserveDialogHandler.doPreProcess(data)
}
override fun onFailure(exception: Exception) {
reserveDialogHandler.doPreProcess(null)
}
})
} else {
reserveDialogHandler.doPreProcess(null)
}
}
/**
* 由于用户预约的游戏个数没有限制为避免一次加载游戏过多这里采用先加载第一页显示出dialog,后续数据在第二页返回
* 注意:当page = 2 时,后台会将后续所有数据一次性返回,所以递归到第三层时,就会结束
* @param isTeenagerMode 青少年模式关闭时才需要启动自动下载,所以当 isTeenagerMode == true 时,不需要加载后续数据,也不需要启动自动下载
*/
@SuppressLint("CheckResult")
private fun loadReserveDialogOnlineData(isTeenagerMode: Boolean, handler: ReserveDialogHandler? = null) {
newApi.getReserveDialog()
.compose(singleToMain())
.subscribe(object : BiResponse<ReserveOnlineEntity>() {
override fun onSuccess(data: ReserveOnlineEntity) {
handler?.doPreProcess(data)
// 继续获取后续需要自动下载的游戏
runOnIoThread {
loadGamesWithAutoDownload(1, 20, isTeenagerMode)
}
}
override fun onFailure(exception: Exception) {
handler?.doPreProcess(null)
}
})
}
/**
* 由于这个方法本身就是在子线程调用的,这里不需要另外在做线程切换
*/
@SuppressLint("CheckResult")
@WorkerThread
private fun loadGamesWithAutoDownload(page: Int, pageSize: Int, isTeenagerMode: Boolean) {
if (page >= 5) {
// 为防止死循环这里设置最多请求到第5页(正常情况下,第一页就是全部数据)
return
}
val filter = "wifi_auto_download:true"
newApi.loadGamesWithAutoDownload(page, pageSize, filter)
.doOnSuccess(::trackAppointmentGameOnlineDialogShow)
.subscribe(object : BiResponse<List<GameEntity>>() {
override fun onSuccess(data: List<GameEntity>) {
// 请注意,这是在子线程中
if (data.isNotEmpty()) {
loadGamesWithAutoDownload(page + 1, pageSize, isTeenagerMode)
startAutoDownloadIfNeed(data, isTeenagerMode)
}
}
})
}
@SuppressLint("CheckResult")
private fun startAutoDownloadIfNeed(games: List<GameEntity>, isTeenagerMode: Boolean) {
val autoDownloadGameIds = mutableSetOf<String>()
games.forEach {
autoDownloadGameIds.add(it.id)
if (it.wifiAutoDownload && !it.isLandPageAddressDialog() && !isTeenagerMode) {
// 开启了 wifi 自动下载,并且不能为第三方落地页跳转
val apk = when (it.getApk().size) {
0 -> null
1 -> it.getApk().first()
else -> {
// 自动下载,多版本默认:九游版
it.getApk().find { apk -> "9u" == apk.getPlatform() && apk.isActive }
}
}
if (apk != null) {
val updateEntities = PackageUtils.getUpdateData(it, false)
val isCanUpdate = if (updateEntities.size == 1) {
true
} else {
// 多版本只需要判断九游版是否需要更新
updateEntities.any { update -> "9u" == update.platform }
}
val isCanPluggable = PackageUtils.isCanPluggable(apk)
if ((!PackageUtils.isInstalled(HaloApp.getInstance(), apk.packageName)
|| isCanUpdate
|| isCanPluggable)
&& DownloadManager.getInstance().getDownloadEntityByUrl(apk.url) == null
) {
// 未下载/可更新/可插件化 且 之前没有下载记录
val msg = FileUtils.isCanDownload(HaloApp.getInstance(), apk.size ?: "")
if (msg.isNullOrBlank()) {
val isWifiOpen = NetworkUtils.isWifiConnected(HaloApp.getInstance())
val isSubscribe = !isWifiOpen
DownloadManager.createDownload(
HaloApp.getInstance(),
apk,
it,
false,
false,
"",
"",
isSubscribe,
ExposureEvent.createEvent(it, listOf(ExposureSource("预约上线弹窗-自动下载", "")))
)
} else {
// 存储空间不足,直接跳出循环,放弃后续的所有游戏
ToastUtils.showToast(msg)
return@forEach
}
}
}
}
}
if (autoDownloadGameIds.isNotEmpty()) {
val body = hashMapOf(
"game_ids" to autoDownloadGameIds,
"type" to "wifi_auto_download"
)
newApi.logAutoDownload(body)
.subscribe({}, {})
}
}
private fun trackAppointmentGameOnlineDialogShow(games: List<GameEntity>) {
if (games.isNotEmpty()) {
val gameIds = arrayListOf<String>()
val gameNames = arrayListOf<String>()
val gameTypes = arrayListOf<String>()
games.forEach { game ->
gameIds.add(game.id)
gameNames.add(game.name ?: "")
gameTypes.add(game.categoryChinese)
}
val gameId = gameIds.joinToString()
val gameName = gameNames.joinToString()
val gameType = gameTypes.joinToString()
SensorsBridge.trackAppointmentGameOnlineDialogShow(gameId, gameName, gameType)
}
}
override fun registerInferiorChain(chain: PriorityChain) {
inferiorChain = chain
if (mainChain.isHandlerQueueEmpty()) {

View File

@ -2,7 +2,7 @@ package com.gh.common.prioritychain
import com.gh.common.iinterface.ISmartRefresh
class PullDownPushHandler(priority: Int): PriorityChainHandler(priority) {
class HomePushHandler(priority: Int): PriorityChainHandler(priority) {
private var mSmartRefreshFragment: ISmartRefresh? = null

View File

@ -39,7 +39,7 @@ class LaunchRedirectHandler(priority: Int) : PriorityChainHandler(priority) {
// 尝试提前设置 tab default 避免首页数据加载完成tab 选中会闪烁
if (launchData?.type == "bottom_tab") {
MainWrapperRepository.getInstance().sendSelectTabEvent(launchData!!)
MainWrapperRepository.getInstance().sendMainSelectTabEvent(launchData!!)
}
if (getStatus() == STATUS_PENDING) {

View File

@ -1,296 +0,0 @@
package com.gh.common.prioritychain
import android.app.Activity
import android.os.Handler
import android.view.LayoutInflater
import android.view.View
import android.widget.PopupWindow
import androidx.constraintlayout.widget.ConstraintLayout
import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.utils.dip2px
import com.gh.gamecenter.common.utils.goneIf
import com.gh.gamecenter.common.view.BugFixedPopupWindow
import com.gh.gamecenter.common.view.NoDefaultMinWidthTabLayout
import com.gh.gamecenter.core.utils.DisplayUtils
import com.gh.gamecenter.core.utils.SPUtils
import com.gh.gamecenter.databinding.PopupMultiTabGuideBinding
import com.gh.gamecenter.entity.BottomTab
import com.gh.gamecenter.wrapper.BaseTabWrapperFragment
import com.gh.gamecenter.wrapper.MainWrapperFragment
import com.google.android.material.tabs.TabLayout
import com.google.android.material.tabs.TabLayout.TabView
class MultiTabGuideHandler(priority: Int): PriorityChainHandler(priority) {
private var mActivity: Activity? = null
private var mHandler: Handler? = null
private var mGuide: BottomTab.Guide? = null
private var mTabLayout: TabLayout? = null
private var mTabView: TabView? = null
private var mIsSingleLineTab = false
private var mMainWrapperFragment: MainWrapperFragment? = null
private var mTabWrapperFragment: BaseTabWrapperFragment? = null
fun doPreProcess(
shouldShow: Boolean,
activity: Activity? = null,
handler: Handler? = null,
guide: BottomTab.Guide? = null,
tabLayout: TabLayout? = null,
tabView: TabLayout.TabView? = null,
isSingleLineTab: Boolean = false,
mainWrapperFragment: MainWrapperFragment? = null,
tabWrapperFragment: BaseTabWrapperFragment? = null
) {
mActivity = activity
mHandler = handler
mGuide = guide
mTabLayout = tabLayout
mTabView = tabView
mIsSingleLineTab = isSingleLineTab
mMainWrapperFragment = mainWrapperFragment
mTabWrapperFragment = tabWrapperFragment
if (getStatus() == STATUS_PENDING) {
if (shouldShow) {
updateStatus(STATUS_VALID)
process()
} else {
processNext()
}
} else {
if (shouldShow) {
updateStatus(STATUS_VALID)
} else {
updateStatus(STATUS_INVALID)
}
}
}
override fun onProcess(): Boolean {
when (getStatus()) {
STATUS_VALID -> {
if (mGuide == null || mActivity == null || mTabView == null || mTabLayout == null) {
processNext()
return false
}
return showMultiTabGuide(
true,
mActivity!!,
mHandler,
mGuide!!,
mTabLayout!!,
mTabView!!,
mIsSingleLineTab,
mMainWrapperFragment,
mTabWrapperFragment
) {
processNext()
}
}
STATUS_INVALID -> {
processNext()
}
}
return false
}
companion object {
private const val TAB_GUIDE_TRIANGLE_OFFSET_DP = 5F
private const val TAB_GUIDE_START_TRIANGLE_OFFSET_DP = 12F
private const val TAB_GUIDE_RIGHT_SIDE_ICON_RIGHT_RESERVED_OFFSET_DP = 51F + TAB_GUIDE_TRIANGLE_OFFSET_DP // 光宝在文案右侧时预留引导到屏幕右侧的距离
private const val TAB_GUIDE_RIGHT_SIDE_ICON_LEFT_RESERVED_OFFSET_DP = TAB_GUIDE_START_TRIANGLE_OFFSET_DP + TAB_GUIDE_TRIANGLE_OFFSET_DP // 光宝在文案作侧时预留引导到屏幕右侧的距离
fun showMultiTabGuide(
isImmediately: Boolean,
activity: Activity,
handler: Handler?,
guide: BottomTab.Guide,
tabLayout: TabLayout,
tabView: TabView,
isSingleLineTab: Boolean = false,
mainWrapperFragment: MainWrapperFragment? = null,
tabWrapperFragment: BaseTabWrapperFragment? = null,
dismissCallback: (() -> Unit)? = null
): Boolean {
val guideSet = HashSet(SPUtils.getStringSet(Constants.SP_MULTI_TAB_NAV_GUIDE_SET))
val hasShownGuide = guideSet.contains(guide.multiTabId + guide.text)
val isCurrentBottomTab = mainWrapperFragment == null || guide.bottomTabId == mainWrapperFragment.currentTab?.id
if (!hasShownGuide && isCurrentBottomTab) {
val screenWidth = DisplayUtils.getScreenWidth(activity)
val outLocation = IntArray(2)
tabView.getLocationOnScreen(outLocation)
val tabViewCenterPosX = outLocation.first() + tabView.width / 2F
val iconLeftMaxPosX = if (isSingleLineTab) tabLayout.width else tabLayout.width - TAB_GUIDE_RIGHT_SIDE_ICON_LEFT_RESERVED_OFFSET_DP.dip2px()
val iconRightMaxPosX = if (isSingleLineTab) tabLayout.width else tabLayout.width - TAB_GUIDE_RIGHT_SIDE_ICON_RIGHT_RESERVED_OFFSET_DP.dip2px()
val isIconLeftValid = tabViewCenterPosX <= iconLeftMaxPosX
val isIconRightValid = tabViewCenterPosX <= iconRightMaxPosX
val isTabViewShowOnScreen = tabViewCenterPosX > 0 && (isIconLeftValid || isIconRightValid)
val isTabLayoutScrollStateIdle = (tabLayout as? NoDefaultMinWidthTabLayout)?.isScrollStateIdle == true
if (isTabViewShowOnScreen && isTabLayoutScrollStateIdle) {
val trianglePosX = tabViewCenterPosX - TAB_GUIDE_TRIANGLE_OFFSET_DP.dip2px()
val guideStartPosX = trianglePosX - TAB_GUIDE_START_TRIANGLE_OFFSET_DP.dip2px()
val xoff = tabView.width / 2 - TAB_GUIDE_START_TRIANGLE_OFFSET_DP.dip2px() - TAB_GUIDE_TRIANGLE_OFFSET_DP.dip2px()
val restGuideWidth = screenWidth - guideStartPosX
showMultiTabPopupWindow(
activity,
handler,
guide,
tabView,
xoff,
screenWidth,
restGuideWidth,
isIconRightValid,
dismissCallback
)
guideSet.add(guide.multiTabId + guide.text)
SPUtils.setStringSet(Constants.SP_MULTI_TAB_NAV_GUIDE_SET, guideSet)
return true
} else if (isImmediately) {
(tabLayout as? NoDefaultMinWidthTabLayout)?.let {
it.onScrollListener = object :
NoDefaultMinWidthTabLayout.OnScrollListener() {
override fun onScrollStateChanged(view: NoDefaultMinWidthTabLayout, scrollState: Int) {
if (scrollState == SCROLL_STATE_IDLE) {
showMultiTabGuideIfTabViewShow(
activity,
handler,
guide,
it,
tabView,
isSingleLineTab,
mainWrapperFragment
)
}
}
}
}
}
} else if (isImmediately && !isCurrentBottomTab) {
tabWrapperFragment?.setResumeAndPauseListener {
if (it) {
handler?.post {
(tabLayout as? NoDefaultMinWidthTabLayout)?.let { tl ->
showMultiTabGuideIfBottomTabShow(
activity,
handler,
guide,
tl,
tabView,
isSingleLineTab,
mainWrapperFragment,
tabWrapperFragment
)
}
}
}
}
}
dismissCallback?.invoke()
return false
}
fun showMultiTabGuideIfTabViewShow(
activity: Activity,
handler: Handler?,
guide: BottomTab.Guide,
tabLayout: NoDefaultMinWidthTabLayout,
tabView: TabView,
isSingleLineTab: Boolean = false,
mainWrapperFragment: MainWrapperFragment?
) {
if (showMultiTabGuide(
false,
activity,
handler,
guide,
tabLayout,
tabView,
isSingleLineTab,
mainWrapperFragment
)
) {
tabLayout.onScrollListener = null
}
}
fun showMultiTabGuideIfBottomTabShow(
activity: Activity,
handler: Handler?,
guide: BottomTab.Guide,
tabLayout: NoDefaultMinWidthTabLayout,
tabView: TabView,
isSingleLineTab: Boolean = false,
mainWrapperFragment: MainWrapperFragment?,
tabWrapperFragment: BaseTabWrapperFragment?
) {
if (showMultiTabGuide(
false,
activity,
handler,
guide,
tabLayout,
tabView,
isSingleLineTab,
mainWrapperFragment,
tabWrapperFragment
)
) {
tabWrapperFragment?.setResumeAndPauseListener(null)
}
}
fun showMultiTabPopupWindow(
activity: Activity,
handler: Handler?,
guide: BottomTab.Guide,
tabView: TabView,
xoff: Int,
screenWidth: Int,
restGuideWidth: Float,
isIconRight: Boolean,
dismissCallback: (() -> Unit)?
): PopupWindow {
val binding = PopupMultiTabGuideBinding.inflate(LayoutInflater.from(activity))
binding.guideTv.text = guide.text
binding.guideTriangleIv.translationX = 12F.dip2px().toFloat()
binding.guideTv.setPadding(if (isIconRight) 8F.dip2px() else 52F.dip2px(), 0, if (isIconRight) 52F.dip2px() else 8F.dip2px(), 0)
binding.guideIconIv.goneIf(!isIconRight)
binding.guideIconFlipIv.goneIf(isIconRight)
val popupWindow = BugFixedPopupWindow(
binding.root,
ConstraintLayout.LayoutParams.WRAP_CONTENT,
ConstraintLayout.LayoutParams.WRAP_CONTENT
)
popupWindow.contentView.measure(View.MeasureSpec.UNSPECIFIED, View.MeasureSpec.UNSPECIFIED)
val measureWidth = popupWindow.contentView.measuredWidth
if (measureWidth >= screenWidth) {
popupWindow.width = screenWidth
binding.guideTriangleIv.translationX += screenWidth - restGuideWidth
} else if (measureWidth > restGuideWidth) {
binding.guideTriangleIv.translationX += measureWidth - restGuideWidth
}
return popupWindow.apply {
isTouchable = false
isFocusable = false
isOutsideTouchable = true
animationStyle = com.gh.gamecenter.common.R.style.popup_window_ease_in_and_out_anim_style
setOnDismissListener {
dismissCallback?.invoke()
}
handler?.post {
if (!activity.isFinishing) {
showAsDropDown(tabView, xoff, (-25F).dip2px())
}
}
}
}
}
}

View File

@ -64,7 +64,7 @@ abstract class PriorityChainHandler(private val mPriority: Int) : Comparable<Pri
* 分发给下一个 handler 处理
*/
fun processNext() {
Utils.log(TAG, "${javaClass.simpleName} processNext")
Utils.log(TAG, "${javaClass.simpleName} processNext $status")
queue?.remove(this)
if (queue?.isEmpty() == true) {

View File

@ -1,28 +0,0 @@
package com.gh.common.prioritychain
import androidx.fragment.app.FragmentActivity
import com.gh.common.util.PackageHelper
import com.gh.gamecenter.common.base.GlobalActivityManager
class RequestInstalledListPermissionHandler : PriorityChainHandler(-1000) {
init {
updateStatus(STATUS_VALID)
}
override fun onProcess(): Boolean {
val currentActivity = GlobalActivityManager.currentActivity ?: return false
if (currentActivity !is FragmentActivity) return false
PackageHelper.showGetInstallAppsListDialogAndRequestPermissionIfNeeded(
activity = currentActivity,
ignorePermanentlyDenied = true
) {
processNext()
}
return true
}
}

View File

@ -2,28 +2,28 @@ package com.gh.common.prioritychain
import androidx.fragment.app.FragmentActivity
import com.gh.common.dialog.ReserveDialog
import com.gh.gamecenter.common.entity.SimpleGameEntity
import com.gh.gamecenter.core.utils.CurrentActivityHolder
import com.gh.gamecenter.feature.entity.ReserveOnlineEntity
class ReserveDialogHandler(priority: Int) : PriorityChainHandler(priority) {
private var mReserveData: ReserveOnlineEntity? = null
private var mReserveData: List<SimpleGameEntity>? = null
/**
* 提前预处理显示弹窗的内容
*/
fun doPreProcess(reserveData: ReserveOnlineEntity?) {
fun doPreProcess(reserveData: List<SimpleGameEntity>?) {
mReserveData = reserveData
if (getStatus() == STATUS_PENDING) {
if (reserveData?.games.isNullOrEmpty()) {
if (reserveData.isNullOrEmpty()) {
processNext()
} else {
updateStatus(STATUS_VALID)
process()
}
} else {
if (reserveData?.games.isNullOrEmpty()) {
if (reserveData.isNullOrEmpty()) {
updateStatus(STATUS_INVALID)
} else {
updateStatus(STATUS_VALID)
@ -37,7 +37,7 @@ class ReserveDialogHandler(priority: Int) : PriorityChainHandler(priority) {
if (GlobalPriorityChainHelper.isThisActivityValid(currentActivity)) {
when (getStatus()) {
STATUS_VALID -> {
val reserveDialog = ReserveDialog.getInstance(mReserveData ?:ReserveOnlineEntity())
val reserveDialog = ReserveDialog.getInstance(mReserveData!!)
reserveDialog.setOnDismissListener {
processNext()
}

View File

@ -1,16 +0,0 @@
package com.gh.common.prioritychain
import com.gh.gamecenter.home.video.ScrollCalculatorHelper
class VideoHandler(priority: Int, val scrollCalculatorHelper: ScrollCalculatorHelper): PriorityChainHandler(priority) {
init {
updateStatus(STATUS_VALID)
}
override fun onProcess(): Boolean {
scrollCalculatorHelper.enableAndPlayIfValid()
return true
}
}

View File

@ -1,6 +1,8 @@
package com.gh.common.prioritychain
import android.graphics.Bitmap
import androidx.fragment.app.FragmentActivity
import com.gh.gamecenter.common.callback.BiCallback
import com.gh.gamecenter.common.utils.ImageUtils
import com.gh.gamecenter.core.utils.CurrentActivityHolder
import com.gh.gamecenter.feature.entity.WelcomeDialogEntity
@ -19,19 +21,20 @@ class WelcomeDialogHandler(priority: Int) : PriorityChainHandler(priority) {
// 判断启动本次应用是否已经弹窗,不是的话弹启动弹窗
if (HaloApp.get(MainWrapperViewModel.SHOULD_SHOW_OPENING_DIALOG, false) == null) {
HaloApp.put(MainWrapperViewModel.SHOULD_SHOW_OPENING_DIALOG, false)
val idealUrl = ImageUtils.getIdealImageUrl(this.welcomeDialogEntity!!.icon, 0, true) ?: ""
ImageUtils.prefetchToDiskCache(idealUrl) { isSuccess ->
if (isSuccess) {
ImageUtils.getBitmap(this.welcomeDialogEntity!!.icon, object : BiCallback<Bitmap, Boolean> {
override fun onFirst(first: Bitmap) {
if (getStatus() == STATUS_PENDING) {
updateStatus(STATUS_VALID)
process()
} else {
updateStatus(STATUS_VALID)
}
} else {
}
override fun onSecond(second: Boolean) {
processNext()
}
}
})
} else {
processNext()
}

View File

@ -7,7 +7,6 @@ import com.gh.gamecenter.R
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.core.provider.IAppProvider
import com.gh.gamecenter.core.provider.IFlavorProvider
import com.gh.gamecenter.va.VCore
import com.halo.assistant.HaloApp
@Route(path = RouteConsts.provider.app, name = "Application暴露服务")
@ -84,13 +83,7 @@ class AppProviderImpl : IAppProvider {
return HaloApp.getInstance().isBrandNewInstall
}
override fun setDisableSplashAdTemporarily(isDisable: Boolean) {
HaloApp.getInstance().isDisableSplashAdTemporarily = isDisable
}
override fun getPluginVersion(): String = VCore.getInstance().getPluginVersion()
override fun initImageLoaderIfNeeded() {
HaloApp.getInstance().initFresco()
override fun setSkippingThirdParty(isSkippingThirdParty: Boolean) {
HaloApp.getInstance().isSkippingThirdParty = isSkippingThirdParty
}
}

View File

@ -32,10 +32,5 @@ class BuildConfigImpl : IBuildConfigProvider {
override fun getVApiHost(): String = BuildConfig.VAPI_HOST
override fun getVDevApiHost(): String = BuildConfig.DEV_VAPI_HOST
override fun getWGameCPMApiHost(): String = BuildConfig.WGAME_CPM_API_HOST
override fun getWGameCPMBusiAppId(): String = BuildConfig.WGAME_CPM_BUSIAPPID
override fun getLogProducerProject(): String = BuildConfig.LOG_HUB_PROJECT
}

View File

@ -1,102 +0,0 @@
package com.gh.common.provider
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.LinearLayout
import android.widget.TextView
import androidx.core.content.ContextCompat
import androidx.viewbinding.ViewBinding
import com.alibaba.android.arouter.facade.annotation.Route
import com.facebook.drawee.view.SimpleDraweeView
import com.gh.common.util.ConcernContentUtils
import com.gh.common.view.ImageContainerView
import com.gh.gamecenter.ImageViewerActivity.Companion.getIntent
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.common.utils.toArrayList
import com.gh.gamecenter.core.provider.IConcernArticleUtilsProvider
import com.gh.gamecenter.databinding.RecyclerGameArticleBinding
@Route(path = RouteConsts.provider.concernContentUtils, name = "ConcernContentUtils暴露服务")
class ConcernArticleUtilsProviderImpl : IConcernArticleUtilsProvider {
override fun addContentPic(
context: Context,
linearLayout: LinearLayout,
list: List<String>,
entrance: String,
width: Int
) {
ConcernContentUtils.addContentPic(context, linearLayout, list, entrance, width)
}
override fun createArticleBinding(parent: ViewGroup): ViewBinding {
val inflater = LayoutInflater.from(parent.context)
return RecyclerGameArticleBinding.inflate(inflater, parent, false)
}
override fun initArticleStyle(binding: ViewBinding) {
if (binding is RecyclerGameArticleBinding) {
val context = binding.root.context
binding.root
.setBackground(ContextCompat.getDrawable(context, com.gh.gamecenter.common.R.drawable.reuse_listview_item_style))
binding.tvGameName.setTextColor(ContextCompat.getColor(context, com.gh.gamecenter.common.R.color.text_primary))
binding.tvTime.setTextColor(ContextCompat.getColor(context, com.gh.gamecenter.common.R.color.text_tertiary))
binding.tvTitle.setTextColor(ContextCompat.getColor(context, com.gh.gamecenter.common.R.color.text_primary))
binding.tvDescription.setTextColor(ContextCompat.getColor(context, com.gh.gamecenter.common.R.color.text_secondary))
binding.tvComment.setTextColor(ContextCompat.getColor(context, com.gh.gamecenter.common.R.color.text_tertiary))
binding.tvShare.setTextColor(ContextCompat.getColor(context, com.gh.gamecenter.common.R.color.text_tertiary))
}
}
override fun getIvIcon(binding: ViewBinding): View =
(binding as RecyclerGameArticleBinding).ivIcon
override fun getTvGameName(binding: ViewBinding): TextView =
(binding as RecyclerGameArticleBinding).tvGameName
override fun getTvTime(binding: ViewBinding): TextView = (binding as RecyclerGameArticleBinding).tvTime
override fun getTvTitle(binding: ViewBinding): TextView = (binding as RecyclerGameArticleBinding).tvTitle
override fun getTvDescription(binding: ViewBinding): TextView =
(binding as RecyclerGameArticleBinding).tvDescription
override fun bindImgs(binding: ViewBinding, img: List<String>) {
if (binding is RecyclerGameArticleBinding) {
val images = img.map {
ImageContainerView.ImageContainerData.ImageInfo(it, 3, 2)
}
val imageContainerData =
ImageContainerView.ImageContainerData("", false, images, show = images.isNotEmpty())
binding.ivImagesContainer.bindData(imageContainerData,
object : ImageContainerView.OnImageContainerEventListener {
override fun onImageClick(
images: List<String>,
position: Int,
imageViewList: ArrayList<SimpleDraweeView>
) {
val checkIntent = getIntent(
binding.root.context,
images.toArrayList(),
position,
imageViewList,
""
)
binding.root.context.startActivity(checkIntent)
}
override fun onVideoCLick(videoId: String) = Unit
})
}
}
override fun getTvComment(binding: ViewBinding): TextView = (binding as RecyclerGameArticleBinding).tvComment
override fun getTvShare(binding: ViewBinding): TextView = (binding as RecyclerGameArticleBinding).tvShare
override fun init(context: Context?) {
// Do nothing
}
}

View File

@ -0,0 +1,26 @@
package com.gh.common.provider
import android.content.Context
import android.widget.LinearLayout
import com.alibaba.android.arouter.facade.annotation.Route
import com.gh.common.util.ConcernContentUtils
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.core.provider.IConcernContentUtilsProvider
@Route(path = RouteConsts.provider.concernContentUtils, name = "ConcernContentUtils暴露服务")
class ConcernContentUtilsProviderImpl : IConcernContentUtilsProvider {
override fun addContentPic(
context: Context,
linearLayout: LinearLayout,
list: List<String>,
entrance: String,
width: Int
) {
ConcernContentUtils.addContentPic(context, linearLayout, list, entrance, width)
}
override fun init(context: Context?) {
// Do nothing
}
}

View File

@ -1,54 +0,0 @@
package com.gh.common.provider
import android.content.Context
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.widget.TextView
import androidx.viewbinding.ViewBinding
import com.alibaba.android.arouter.facade.annotation.Route
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.common.utils.goneIf
import com.gh.gamecenter.common.utils.toColor
import com.gh.gamecenter.core.provider.IConcernGiftPackUtilsProvider
import com.gh.gamecenter.databinding.RecyclerGiftPackBinding
@Route(path = RouteConsts.provider.concernGiftPackUtils, name = "ConcernGiftPackUtils暴露服务")
class ConcernGiftPackUtilsProviderImpl : IConcernGiftPackUtilsProvider {
override fun createBinding(parent: ViewGroup): ViewBinding {
val inflater = LayoutInflater.from(parent.context)
return RecyclerGiftPackBinding.inflate(inflater, parent, false)
.also {
it.gCode.goneIf(true)
}
}
override fun initStyle(viewBinding: ViewBinding) {
with(viewBinding as RecyclerGiftPackBinding) {
val context = root.context
tvGameName.setTextColor(com.gh.gamecenter.common.R.color.text_primary.toColor(context))
tvTime.setTextColor(com.gh.gamecenter.common.R.color.text_tertiary.toColor(context))
tvGiftPackName.setTextColor(com.gh.gamecenter.common.R.color.text_primary.toColor(context))
tvGiftPackContent.setTextColor(com.gh.gamecenter.common.R.color.text_secondary.toColor(context))
}
}
override fun getIvGameIcon(viewBinding: ViewBinding) =
(viewBinding as RecyclerGiftPackBinding).ivIcon
override fun getTvGameName(viewBinding: ViewBinding) =
(viewBinding as RecyclerGiftPackBinding).tvGameName
override fun getTvTime(viewBinding: ViewBinding) =
(viewBinding as RecyclerGiftPackBinding).tvTime
override fun getTvGiftPackName(viewBinding: ViewBinding) =
(viewBinding as RecyclerGiftPackBinding).tvGiftPackName
override fun getTvGiftPackContent(viewBinding: ViewBinding) =
(viewBinding as RecyclerGiftPackBinding).tvGiftPackContent
override fun init(context: Context?) {
// Do Nothing
}
}

View File

@ -1,19 +0,0 @@
package com.gh.common.provider
import android.content.Context
import androidx.appcompat.app.AppCompatActivity
import com.alibaba.android.arouter.facade.annotation.Route
import com.gh.gamecenter.common.constant.RouteConsts
import com.gh.gamecenter.core.provider.IConcernShareNewsProvider
import com.gh.gamecenter.newsdetail.NewsShareDialog
@Route(path = RouteConsts.provider.concernShareNews, name = "ConcernShareNews暴露服务")
class ConcernShareNewsProviderImpl : IConcernShareNewsProvider {
override fun share(activity: AppCompatActivity, shortId: String?, id: String?, gameIcon: String?, title: String?) {
NewsShareDialog.show(activity, shortId, id, gameIcon, title)
}
override fun init(context: Context?) {
// Do Nothing
}
}

View File

@ -100,10 +100,6 @@ class ConfigProviderImpl : IConfigProvider {
return Config.getNightModeSetting()?.setting ?: false
}
override fun isJiguangSwitch(): Boolean {
return Config.getNewApiSettingsEntity()?.jiguangSwitch ?: false
}
override fun init(context: Context?) {
// Do nothing
}

View File

@ -13,10 +13,9 @@ class DefaultUrlHandlerProviderImpl : IDefaultUrlHandlerProvider {
context: Context,
url: String,
entrance: String,
bringAppToFront: Boolean,
sourceEntrance: String
bringAppToFront: Boolean
): Boolean {
return DefaultUrlHandler.interceptUrl(context, url, null, entrance, bringAppToFront, sourceEntrance)
return DefaultUrlHandler.interceptUrl(context, url, null, entrance, bringAppToFront)
}
override fun init(context: Context?) {

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