Compare commits

...

55 Commits

Author SHA1 Message Date
6f7374c479 版本更新到 5.5.7-458 2022-01-21 15:53:29 +08:00
7e296ae7ab Merge branch 'hotfix-v5.5.7-457-article_comment' into 'release'
修改帖子评论复用问题

See merge request halo/android/assistant-android!197
2022-01-21 15:46:39 +08:00
f5a985b221 修改帖子评论复用问题 2022-01-21 15:16:50 +08:00
f719ec10a7 版本更新至 5.5.7 2022-01-21 10:10:23 +08:00
b680d723b1 Merge branch 'hotfix-v5.6.6-456-wrong_so_crash' into 'release'
修复部分 5.1.1 设备加载错误 so 的问题

See merge request halo/android/assistant-android!196
2022-01-21 10:07:23 +08:00
0cf410c768 修复部分 5.1.1 设备加载错误 so 的问题 2022-01-21 10:04:23 +08:00
3c255a7119 Merge branch 'hotfix_5.5.6-456-crashes' into 'release'
修复sentry一些闪退问题

See merge request halo/android/assistant-android!195
2022-01-20 10:40:35 +08:00
d9c5c7ffc4 修复WebActivity关闭Dialog闪退
修复首页游戏单安利墙组件闪退问题
2022-01-20 10:36:08 +08:00
e594703f8f Merge branch 'flutter-release' into 'release'
调整 FlutterBoost 的初始化时机

See merge request halo/android/assistant-android!194
2022-01-19 17:39:09 +08:00
cd98550183 调整 FlutterBoost 的初始化时机 2022-01-19 17:37:54 +08:00
c2cbfad51f 版本更新至 5.5.6 2022-01-19 11:29:56 +08:00
9848c3d07e Merge branch 'hotfix_5.5.5-455-forced_static_image_on_buggy_device' into 'release'
在特殊设备上禁用动图

See merge request halo/android/assistant-android!192
2022-01-19 10:59:41 +08:00
84a2d9cdba 在特殊设备上禁用动图 2022-01-19 10:59:41 +08:00
f2438f80e0 Merge branch 'flutter-release' into 'release'
issue 1567

See merge request halo/android/assistant-android!191
2022-01-18 17:37:15 +08:00
824d8897aa issue 1567 2022-01-18 17:37:15 +08:00
1d4333ffe4 Merge branch 'hotfix-v5.5.4-454-fix_launch_type' into 'release'
修复启动类型上报异常问题

See merge request halo/android/assistant-android!188
2022-01-18 15:12:10 +08:00
337bbe7ec3 修复启动类型上报异常问题 2022-01-18 15:11:16 +08:00
fd482f32f0 Merge branch 'hotfix-v5.5.4-454-argument_error' into 'release'
修改我的收藏、历史记录页面参数传递错误

See merge request halo/android/assistant-android!187
2022-01-18 14:05:45 +08:00
755e4f24ff 修改我的收藏、历史记录页面参数传递错误 2022-01-18 12:11:16 +08:00
2f1137b97b Merge branch 'hotfix-v5.5.4-454-generic_crash' into 'release'
Hotfix v5.5.4 454 generic crash

See merge request halo/android/assistant-android!185
2022-01-18 10:21:36 +08:00
78541a56f8 调整包被篡改后的闪退提示弹窗 2022-01-18 10:18:29 +08:00
7d9a0d3308 尝试修复 Fresco 未能被正常初始化的问题 2022-01-18 10:18:29 +08:00
5bef19fac2 Merge branch 'hotfix-v5.5.4-454-generic_crash' into 'release'
修复 5.5.4 的一些闪退

See merge request halo/android/assistant-android!184
2022-01-18 09:25:08 +08:00
beb1c95a2b 修复 5.5.4 的一些闪退
1. 捕抓选择图片上传时的异常
2. 捕抓骨架图在老旧 oppo 设备上的夜间模式闪退
2022-01-18 09:25:08 +08:00
4bd2d0aff7 Merge branch 'hotfix-v5.5.4-454-generic_crash' into 'release'
修复一些闪退

See merge request halo/android/assistant-android!183
2022-01-17 17:58:17 +08:00
ca73e267d8 Merge branch 'hotfix-v5.5.4-454-crashes' into 'release'
修改sentry上一些闪退问题

See merge request halo/android/assistant-android!182
2022-01-17 17:57:28 +08:00
628b91eed8 修复一些闪退
1. 修复未成年弹窗偶发的闪退
2. 捕抓富文本点击闪退
3. 修复首页轮播图偶发的数组越界闪退
2022-01-17 17:56:36 +08:00
9c56b67dcc 1.修改帖子详情闪退问题
2.修改视频贴评论页还未显示出来点击评论闪退问题
3.修改视频帖信息展开功能闪退问题
2022-01-17 16:36:07 +08:00
f4e7c9acc5 Merge branch 'hotfix-v5.5.4-454-my_game_activity_crash' into 'release'
修复我的游戏页显示右上角引导图导致的闪退问题

See merge request halo/android/assistant-android!181
2022-01-17 16:26:52 +08:00
lyr
0a94a27331 修复我的游戏页显示右上角引导图导致的闪退问题 2022-01-17 16:24:21 +08:00
62d6ea002d 版本更新至 5.5.5 2022-01-17 10:02:06 +08:00
e0aa84c877 Merge branch 'hotfix-v5.5.4-454-fix_wrong_so_loaded' into 'release'
尝试修复 VIVO 和 OPPO 设备加载错误 SO 的问题

See merge request halo/android/assistant-android!180
2022-01-17 10:00:57 +08:00
25f4c027bf 尝试修复 VIVO 和 OPPO 设备加载错误 SO 的问题 2022-01-17 09:59:08 +08:00
56f817bb7a Merge branch 'dev' into 'release'
修复下载管理sentry问题

See merge request halo/android/assistant-android!179
2022-01-13 14:43:54 +08:00
1b976106e4 尝试修复下载管理游戏更新列表数组越界闪退 2022-01-13 11:02:16 +08:00
0e3ab3c3a7 Merge branch 'hotfix-v5.5.3-453-crash' into 'release'
修改sentry上闪退问题

See merge request halo/android/assistant-android!178
2022-01-13 09:10:53 +08:00
948588b874 1.修改外部浏览器跳转app闪退问题 2.修改帖子详情空指针问题 2022-01-12 19:55:10 +08:00
095139079e 修复下载管理已安装列表空指针闪退 尝试修复数组越界闪退 2022-01-12 17:40:16 +08:00
228ab0ca40 Merge branch 'hotfix-v5.5.3-453-room_crash' into 'release'
尝试处理数据库的CursorWindowAllocationException异常

See merge request halo/android/assistant-android!176
2022-01-12 14:11:06 +08:00
fdcb7cbbf7 Merge branch 'hotfix-v5.5.3-453-optimizate' into 'release'
修复游戏单、搜索论坛问题

See merge request halo/android/assistant-android!175
2022-01-12 11:21:38 +08:00
933f46e250 1.修改游戏单选择游戏列表复用问题
2.修改论坛搜索页热门论坛超过20个闪退问题
2022-01-12 11:08:44 +08:00
2282787bd7 Merge branch 'hotfix-v5.5.3-453-wrong_so_crash' into 'release'
再次启用 64 位 SO, 尝试修复部分 5.0 & 5.1 设备依旧读取错误图片 SO 的问题

See merge request halo/android/assistant-android!174
2022-01-12 10:52:08 +08:00
c4d3698a9b 再次启用 64 位 SO, 尝试修复部分 5.0 & 5.1 设备依旧读取错误图片 SO 的问题 2022-01-12 10:50:29 +08:00
80cc86a791 尝试处理数据库的CursorWindowAllocationException异常 2022-01-12 10:30:38 +08:00
3646672849 版本更新至 5.5.4 2022-01-11 17:26:15 +08:00
9a4c8f1f06 Merge branch 'dev' into 'release'
合并 5.5.0 游戏单活动

See merge request halo/android/assistant-android!173
2022-01-11 17:16:39 +08:00
ce303b37b7 修复下载管理已安装列表在安装/卸载游戏后的显示异常 2022-01-10 17:50:39 +08:00
0bbffb20cd Merge branch 'release' into 'dev'
Merge hotfix from release

See merge request halo/android/assistant-android!172
2022-01-05 11:49:50 +08:00
415626ef58 版本更新至 5.5.3 2022-01-04 16:25:03 +08:00
lyr
fc5de50f61 【光环助手V5.5.0】游戏单活动:解锁好游种草新姿势(1230测试 7)https://git.shanqu.cc/pm/halo-app-issues/-/issues/1638#note_130160 2021-12-31 16:43:59 +08:00
lyr
b896af2a15 【光环助手V5.5.0】游戏单活动:解锁好游种草新姿势(完善"url参数增加是否可以由web端处理返回键")https://git.shanqu.cc/pm/halo-app-issues/-/issues/1638#note_129888 2021-12-30 19:10:10 +08:00
lyr
93ba447192 【光环助手V5.5.0】游戏单活动:解锁好游种草新姿势(url参数增加是否可以由web端处理返回键)https://git.shanqu.cc/pm/halo-app-issues/-/issues/1638 2021-12-30 16:56:15 +08:00
lyr
c3cf93eaee 【光环助手V5.5.0】游戏单活动:解锁好游种草新姿势(更新递增任务进度接口)https://git.shanqu.cc/pm/halo-app-issues/-/issues/1638#note_129888 2021-12-29 18:32:32 +08:00
6da3d46d71 Merge branch 'feature-issues1638' into 'dev'
【光环助手V5.5.0】游戏单活动:解锁好游种草新姿势(客户端部分)https://git.shanqu.cc/pm/halo-app-issues/-/issues/1638

See merge request halo/android/assistant-android!156
2021-12-27 11:07:31 +08:00
a26e61ae4b 【光环助手V5.5.0】游戏单活动:解锁好游种草新姿势(客户端部分)https://git.shanqu.cc/pm/halo-app-issues/-/issues/1638 2021-12-27 11:07:31 +08:00
66 changed files with 894 additions and 316 deletions

View File

@ -61,7 +61,7 @@ android {
// couldn't find DSO to load: libimagepipeline.so caused by: dlopen failed: "/data/data/com.gh.gamecenter/lib-main/libimagepipeline.so" is 64-bit instead of 32-bit result: 0
// 以 OPPO R7PLUS 为例,明明设备是骁龙 615ARMv8-64 bit 的设备却不支持 arm64 的 abi限制了只使用 java 后还是报错,只有 5.05.1 设备无法复现 : (
// 惊了
abiFilters "armeabi-v7a", "x86"
abiFilters "armeabi-v7a", "arm64-v8a", "x86"
}
renderscriptTargetApi 18
@ -82,6 +82,7 @@ android {
* All third-party appid/appkey
*/
buildConfigField "String", "API_HOST", "\"${API_HOST}\""
buildConfigField "String", "NEW_API_HOST", "\"${NEW_API_HOST}\""
buildConfigField "String", "WECHAT_APPID", "\"${WECHAT_APPID}\""
buildConfigField "String", "WECHAT_SECRET", "\"${WECHAT_SECRET}\""
buildConfigField "String", "TENCENT_APPID", "\"${TENCENT_APPID}\""
@ -171,6 +172,7 @@ android {
versionNameSuffix "-debug"
buildConfigField "String", "DEV_API_HOST", "\"${DEV_API_HOST}\""
buildConfigField "String", "NEW_DEV_API_HOST", "\"${NEW_DEV_API_HOST}\""
}
// publish release host˛
@ -178,12 +180,14 @@ android {
dimension "env"
buildConfigField "String", "DEV_API_HOST", "\"${API_HOST}\""
buildConfigField "String", "NEW_DEV_API_HOST", "\"${NEW_API_HOST}\""
}
tea {
dimension "env"
buildConfigField "String", "DEV_API_HOST", "\"${API_HOST}\""
buildConfigField "String", "NEW_DEV_API_HOST", "\"${NEW_API_HOST}\""
manifestPlaceholders.put("APPLOG_SCHEME", "rangersapplog.byAx6uYt".toLowerCase())
}
@ -192,6 +196,7 @@ android {
dimension "env"
buildConfigField "String", "DEV_API_HOST", "\"${API_HOST}\""
buildConfigField "String", "NEW_DEV_API_HOST", "\"${NEW_API_HOST}\""
}
}
@ -335,7 +340,7 @@ dependencies {
implementation "org.nanohttpd:nanohttpd:${nanohttpd}"
implementation "com.aliyun.openservices:aliyun-log-android-sdk:${aliyunLog}"
implementation "com.github.princekin-f:EasyFloat:${easyFloat}"
implementation "com.lg:easyfloat:${easyFloat}"
implementation "io.github.florent37:shapeofview:${shapeOfView}"

View File

@ -71,7 +71,7 @@ class GlobalActivityLifecycleObserver : Application.ActivityLifecycleCallbacks {
override fun onActivityPaused(activity: Activity) {
CurrentActivityHolder.activitySet.remove(activity)
FloatingBackViewManager.dismissBackView(activity)
FloatingBackViewManager.dismissBackView()
if (HaloApp.isUserAcceptPrivacyPolicy(activity)) {
DataUtils.onPause(activity)

View File

@ -14,10 +14,7 @@ import com.gh.common.loghub.LoghubUtils
import com.gh.common.tracker.Tracker
import com.gh.common.util.*
import com.gh.common.view.dsbridge.CompletionHandler
import com.gh.gamecenter.BuildConfig
import com.gh.gamecenter.ImageViewerActivity
import com.gh.gamecenter.LoginActivity
import com.gh.gamecenter.WebActivity
import com.gh.gamecenter.*
import com.gh.gamecenter.energy.EnergyCenterActivity
import com.gh.gamecenter.energy.EnergyHouseActivity
import com.gh.gamecenter.entity.Badge
@ -397,6 +394,20 @@ class DefaultJsApi(var context: Context) {
runOnUiThread { DirectUtils.directToFullScreenWebPage(context, url.toString(), true) }
}
@JavascriptInterface
fun startGameCollectionSquareBrowseTask(event: Any) {
val browseTimeEvent = event.toString().toObject() ?: BrowseTaskEvent()
GameCollectionSquareBrowseTaskHelper.enableBrowseTimeCount(
browseTimeEvent.timeout.toInt(),
browseTimeEvent.isFinished == "true"
)
}
@JavascriptInterface
fun checkUpdateGhzs(msg: Any) {
context.startActivity(AboutActivity.getIntent(context, true));
}
@Keep
internal data class ImageEvent(var imageList: ArrayList<String> = arrayListOf(), var position: Int = 0)
@ -411,4 +422,7 @@ class DefaultJsApi(var context: Context) {
@Keep
internal data class LogEvent(var jsonString: String = "", var logStore: String = "")
@Keep
internal data class BrowseTaskEvent(var timeout: String = "", var isFinished: String = "")
}

View File

@ -18,6 +18,7 @@ import com.gh.common.util.DirectUtils.directToQa
import com.gh.common.util.GsonUtils.gson
import com.gh.gamecenter.*
import com.gh.gamecenter.entity.*
import com.gh.gamecenter.gamecollection.publish.GameCollectionEditActivity
import com.gh.gamecenter.qa.BbsType
import com.gh.gamecenter.qa.video.publish.VideoPublishActivity
import com.gh.gamecenter.subject.SubjectActivity
@ -375,11 +376,18 @@ object DefaultUrlHandler {
}
}
EntranceUtils.HOST_GAME_COLLECTION_DETAIL -> {
DirectUtils.directToGameCollectionDetail(context, id, entrance)
}
EntranceUtils.HOST_GAME_COLLECTION_SQUARE -> {
DirectUtils.directToGameCollectionSquare(context, entrance)
}
EntranceUtils.HOST_GAME_COLLECTION_EDIT -> {
context.startActivity(GameCollectionEditActivity.getIntent(context, entrance))
}
else -> DialogHelper.showUpgradeDialog(context)
}
return true

View File

@ -38,6 +38,7 @@ public class Config {
// 这个 API_HOST 在测试包里会随着选择的环境切换,正式包里会一直保持正式 host
public static final String API_HOST = EnvHelper.getHost();
public static final String NEW_API_HOST = EnvHelper.getNewHost();
/**
* 需要配置的请使用{@link PreferenceManager#getDefaultSharedPreferences(Context)}

View File

@ -357,6 +357,10 @@ public class Constants {
public static final String GAME_COLLECTION_SHARE_ADDRESS_DEV = "https://dev-and-static.ghzs.com/web/game_collection/index.html#/?from=ghzs";
public static final String GAME_COLLECTION_SHARE_ADDRESS = "https://and-static.ghzs.com/web/game_collection/index.html#/?from=ghzs";
// 游戏单活动分享链接 https://git.shanqu.cc/pm/halo-app-issues/-/issues/1638
public static final String GAME_COLLECTION_ACTIVITY_ADDRESS_DEV = "https://dev-and-static.ghzs.com/web/ghzs_activity/haoyouUnlock.html";
public static final String GAME_COLLECTION_ACTIVITY_ADDRESS = "https://and-static.ghzs.com/web/ghzs_activity/haoyouUnlock.html";
// 青少年模式找回密码
public static final String TEEN_MODE_RESET_PASSWORD = "https://resource.ghzs.com/page/privacy_policies/help_password.html";

View File

@ -0,0 +1,38 @@
package com.gh.common.image
import com.facebook.imagepipeline.common.ImageDecodeOptions
import com.facebook.imagepipeline.decoder.ImageDecoder
import com.facebook.imagepipeline.image.CloseableImage
import com.facebook.imagepipeline.image.EncodedImage
import com.facebook.imagepipeline.image.QualityInfo
class EmptyDecoder : ImageDecoder {
override fun decode(
encodedImage: EncodedImage,
length: Int,
qualityInfo: QualityInfo,
options: ImageDecodeOptions
): CloseableImage {
return object : CloseableImage() {
override fun close() {
// do nothing
}
override fun getWidth(): Int {
return 0
}
override fun getHeight(): Int {
return 0
}
override fun getSizeInBytes(): Int {
return 0
}
override fun isClosed(): Boolean {
return true
}
}
}
}

View File

@ -39,7 +39,7 @@ object DeviceTokenUtils {
}
@JvmStatic
fun getLaunchType(): LunchType {
fun getLaunchType(readOnly: Boolean = false): LunchType {
var lunchType: LunchType? = null
val values = PreferenceManager.getDefaultSharedPreferences(HaloApp.getInstance().application).all
// 版本更新
@ -64,7 +64,10 @@ object DeviceTokenUtils {
if (deviceId.isNullOrEmpty()) {
deviceId = Utils.getTime(HaloApp.getInstance().application).toString()
}
setDeviceId(deviceId)
if (!readOnly) {
setDeviceId(deviceId)
}
return lunchType
}

View File

@ -68,6 +68,7 @@ import com.gh.gamecenter.video.detail.VideoDetailContainerViewModel
import com.gh.gamecenter.video.game.GameVideoActivity
import com.gh.gamecenter.video.videomanager.VideoManagerActivity
import com.halo.assistant.HaloApp
import com.halo.assistant.fragment.WebFragment
import com.lightgame.utils.Utils
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.schedulers.Schedulers
@ -741,6 +742,9 @@ object DirectUtils {
} else {
bundle.putString(KEY_TO, WebActivity::class.java.simpleName)
}
if (url.contains("leave_web_page_handle_back_pressed=true")) {
bundle.putBoolean(WebFragment.KEY_LEAVE_WEB_PAGE_TO_HANDLE_BACK_PRESSED, true)
}
bundle.putString(EntranceUtils.KEY_URL, url)
jumpActivity(context, bundle)
}

View File

@ -97,6 +97,8 @@ public class EntranceUtils {
public static final String HOST_HELP_DETAIL = "help_detail";
public static final String HOST_HELP_SUGGESTION = "help_suggestion";
public static final String HOST_GAME_COLLECTION_DETAIL = "game_collection_detail";
public static final String HOST_GAME_COLLECTION_SQUARE = "game_collection_square";
public static final String HOST_GAME_COLLECTION_EDIT = "game_collection_edit";
public static final String KEY_DATA = "data";
public static final String KEY_MESSAGE = "message";
public static final String KEY_MESSAGE_ID = "message_id";

View File

@ -24,6 +24,19 @@ object EnvHelper {
}
}
@JvmStatic
fun getNewHost(): String {
return if (!isTestEnv()) {
BuildConfig.NEW_API_HOST
} else {
if (isDevEnv) {
BuildConfig.NEW_DEV_API_HOST
} else {
BuildConfig.NEW_API_HOST
}
}
}
// 包体是否为测试包
@JvmStatic
fun isTestEnv(): Boolean {

View File

@ -91,8 +91,8 @@ object FloatingBackViewManager {
* 隐藏返回小浮窗
*/
@JvmStatic
fun dismissBackView(activity: Activity) {
EasyFloat.dismiss(activity, FLOATING_BACK_VIEW)
fun dismissBackView() {
EasyFloat.dismiss(FLOATING_BACK_VIEW)
}
fun getType(): String {

View File

@ -0,0 +1,226 @@
package com.gh.common.util
import android.annotation.SuppressLint
import android.app.Activity
import android.app.Application
import android.os.Build
import android.os.Bundle
import android.view.Gravity
import android.widget.ImageView
import android.widget.ProgressBar
import com.gh.base.CurrentActivityHolder
import com.gh.base.GHThreadFactory
import com.gh.common.runOnUiThread
import com.gh.gamecenter.NormalActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.gamecollection.detail.GameCollectionDetailActivity
import com.gh.gamecenter.gamecollection.square.GameCollectionSquareActivity
import com.gh.gamecenter.retrofit.BiResponse
import com.gh.gamecenter.retrofit.RetrofitManager
import com.halo.assistant.HaloApp
import com.lzf.easyfloat.EasyFloat
import com.lzf.easyfloat.enums.ShowPattern
import com.lzf.easyfloat.enums.SidePattern
import okhttp3.ResponseBody
import java.util.concurrent.ExecutorService
import java.util.concurrent.Executors
/**
* 浏览游戏单广场任务辅助类
*/
@SuppressLint("StaticFieldLeak")
object GameCollectionSquareBrowseTaskHelper {
const val KEY_IS_FORM_BROWSE_TASK = "is_from_browse_task"
private const val FLOATING_SQUARE_BROWSE_TASK_VIEW = "floating_square_browse_task_view"
private var mBrowseTimeCount = 0
private var mIsBrowseTimeCountEnabled = false // 游戏单广场浏览时间统计是否开启
private var mBrowseTimeTimeout = 15
private var mIsBrowseTimeCountValid = false // 游戏单广场浏览时间统计是否有效
private var mBrowsePro: ProgressBar? = null
private var mIsFinished = false
private var mNeedShowFloatView = false
private var mIsFirstEnterSquare = true
private val mThreadService: ExecutorService by lazy {
Executors.newSingleThreadExecutor(GHThreadFactory("BROWSE_SQUARE_THREAD"))
}
private val mActivityLifecycleCallbacks by lazy {
object : Application.ActivityLifecycleCallbacks {
override fun onActivityCreated(activity: Activity, savedInstanceState: Bundle?) {}
override fun onActivityStopped(activity: Activity) {}
override fun onActivitySaveInstanceState(activity: Activity, outState: Bundle) {}
override fun onActivityStarted(activity: Activity) {}
override fun onActivityResumed(activity: Activity) {
if (isTopActivityGameCollectionRelated(activity) && mIsBrowseTimeCountEnabled) {
resumeTimeCount()
} else if (isGameCollectionSquare(activity) && mNeedShowFloatView) {
showOrUpdateFloatView(activity, mBrowseTimeTimeout)
}
}
override fun onActivityPaused(activity: Activity) {
if (isTopActivityGameCollectionRelated(activity) && mIsBrowseTimeCountEnabled) {
pauseTimeCount()
}
if (isGameCollectionSquare(activity)) {
dismissFloatView()
}
}
override fun onActivityDestroyed(activity: Activity) {
if (isGameCollectionSquare(activity) && mIsBrowseTimeCountEnabled) {
disableBrowseTimeCount()
unregisterActivityLifecycleCallbacks()
}
}
}
}
fun enableBrowseTimeCount(timeout: Int, isFinished: Boolean) {
mIsBrowseTimeCountEnabled = true
mBrowseTimeTimeout = timeout
mIsFinished = isFinished
mNeedShowFloatView = true
mIsFirstEnterSquare = true
resumeTimeCount()
HaloApp.getInstance().registerActivityLifecycleCallbacks(mActivityLifecycleCallbacks)
}
fun disableBrowseTimeCount() {
mBrowseTimeCount = 0
mIsBrowseTimeCountEnabled = false
mBrowsePro = null
mIsFinished = false
mIsFirstEnterSquare = true
}
fun unregisterActivityLifecycleCallbacks() {
mNeedShowFloatView = false
HaloApp.getInstance().unregisterActivityLifecycleCallbacks(mActivityLifecycleCallbacks)
}
fun resumeTimeCount() {
if (!mIsBrowseTimeCountEnabled) return
mIsBrowseTimeCountValid = true
mThreadService.execute {
while (mIsBrowseTimeCountEnabled && mIsBrowseTimeCountValid) {
val topActivity = CurrentActivityHolder.getCurrentActivity() ?: continue
if (isGameCollectionSquare(topActivity, false) && mIsFirstEnterSquare) {
mIsFirstEnterSquare = false
topActivity.intent.putExtra(KEY_IS_FORM_BROWSE_TASK, true)
}
if (isTopActivityGameCollectionRelated(topActivity)) {
tryWithDefaultCatch {
showOrUpdateFloatView(topActivity, if (mIsFinished) mBrowseTimeTimeout else mBrowseTimeCount)
if (mIsFinished) {
disableBrowseTimeCount()
} else {
mBrowseTimeCount++
if (mBrowseTimeCount >= mBrowseTimeTimeout) {
showOrUpdateFloatView(topActivity, mBrowseTimeTimeout)
postBrowseFinish()
}
}
}
}
Thread.sleep(1000)
}
}
}
fun pauseTimeCount() {
if (!mIsBrowseTimeCountEnabled) return
mIsBrowseTimeCountValid = false
}
// 从任务跳转的游戏单广场/此游戏单广场进入的游戏单详情都计时
private fun isTopActivityGameCollectionRelated(activity: Activity): Boolean {
return isGameCollectionSquare(activity)
|| (activity is GameCollectionDetailActivity
&& activity.intent.getBundleExtra(NormalActivity.NORMAL_FRAGMENT_BUNDLE)?.getBoolean(KEY_IS_FORM_BROWSE_TASK) == true)
}
private fun isGameCollectionSquare(activity: Activity, checkIsFromTask: Boolean = true): Boolean {
return activity is GameCollectionSquareActivity
&& (!checkIsFromTask || activity.intent.getBooleanExtra(KEY_IS_FORM_BROWSE_TASK, false))
}
private fun showOrUpdateFloatView(activity: Activity, time: Int) {
// 不支持 Android 4.1 的设备
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.JELLY_BEAN) return
// 游戏单广场才显示FloatView
if (!isGameCollectionSquare(activity)) return
runOnUiThread {
val isFinished = time == mBrowseTimeTimeout
val floatView = EasyFloat.getFloatView(FLOATING_SQUARE_BROWSE_TASK_VIEW)
if (floatView != null) {
if (mBrowsePro == null) {
mBrowsePro = floatView.findViewById(R.id.browsePro)
}
mBrowsePro?.progress = time
if (isFinished) {
floatView.findViewById<ImageView>(R.id.browsePic)
.setImageResource(R.drawable.pic_browse_square_finish)
}
} else {
EasyFloat.with(activity)
.setLayout(R.layout.layout_square_browse_task_float)
.setTag(FLOATING_SQUARE_BROWSE_TASK_VIEW)
.setAnimator(null)
.setGravity(Gravity.END.or(Gravity.CENTER_VERTICAL), 0, 0)
.setSidePattern(SidePattern.RIGHT)
.setShowPattern(ShowPattern.CURRENT_ACTIVITY)
.setDragEnable(false)
.registerCallback {
createResult { _, _, view ->
if (isFinished) {
view?.findViewById<ProgressBar>(R.id.browsePro)?.run {
max = mBrowseTimeTimeout
progress = mBrowseTimeTimeout
}
view?.findViewById<ImageView>(R.id.browsePic)
?.setImageResource(R.drawable.pic_browse_square_finish)
} else {
view?.findViewById<ProgressBar>(R.id.browsePro)?.run {
mBrowsePro = this
max = mBrowseTimeTimeout
progress = 0
}
view?.findViewById<ImageView>(R.id.browsePic)
?.setImageResource(R.drawable.pic_browse_square)
}
}
}
.show()
}
}
}
fun dismissFloatView() {
EasyFloat.dismiss(FLOATING_SQUARE_BROWSE_TASK_VIEW)
}
@SuppressLint("CheckResult")
private fun postBrowseFinish() {
RetrofitManager.getInstance(HaloApp.getInstance())
.newApi
.postGameCollectionTask("browse_game_list_square", "0")
.compose(singleToMain())
.subscribe(object : BiResponse<ResponseBody>() {
override fun onSuccess(data: ResponseBody) {
disableBrowseTimeCount()
}
})
}
}

View File

@ -49,6 +49,9 @@ object ImageUtils {
const val TARGET_WIDTH = R.dimen.width_placeholder
// 是否仅显示静态 PNG 图片 (gif 会转码为静态图片)
private var mDisplayStaticPngOnly = false
private val mImageUrlCacheSet by lazy { FixedSizeLinkedHashSet<String>(maxSize = 200) }
private val mImageDecorationThread by lazy {
Executors.newSingleThreadExecutor(
@ -56,6 +59,14 @@ object ImageUtils {
)
}
/**
* 禁用动图,全局设置
*/
@JvmStatic
fun disableAnimatedImage() {
mDisplayStaticPngOnly = true
}
@JvmStatic
fun getUploadFileMaxSize(): Long {
val uploadLimitSize = Config.getSettings()?.image?.uploadLimitSize
@ -97,8 +108,14 @@ object ImageUtils {
@JvmStatic
fun addLimitWidth(imageUrl: String?, width: Int?): String? {
val jpegConfig = Config.getSettings()?.image?.oss?.jpeg
val webpConfig = Config.getSettings()?.image?.oss?.webp
var webpConfig = Config.getSettings()?.image?.oss?.webp
?: Config.getSettings()?.image?.oss?.gif
// 全部图片转 png
if (mDisplayStaticPngOnly) {
webpConfig = "?x-oss-process=image/format,png/quality,q_90"
}
if (imageUrl?.contains("?x-oss-process") == false && jpegConfig != null) {
return if (width == 0 || width == null) {
"$imageUrl$webpConfig"
@ -378,7 +395,7 @@ object ImageUtils {
processor: Postprocessor? = null
) {
mImageDecorationThread.execute {
if (url == null) return@execute
if (url.isNullOrEmpty()) return@execute
// 部分自适应宽高图片需要一个 TARGET_WIDTH 来避免加载过小图片
val width = (view?.getTag(TARGET_WIDTH) as? Int)
@ -432,7 +449,7 @@ object ImageUtils {
if (shouldLoadAsGif && view?.tag == url) return@execute
if (!shouldLoadAsGif) {
if (!shouldLoadAsGif || mDisplayStaticPngOnly) {
highResUrl = getTransformedUrl(url, width ?: 0) ?: ""
loadImageClosure(shouldLoadAsGif, highResUrl, lowResUrl)
} else {

View File

@ -75,6 +75,9 @@ public class IntentUtils {
} else {
cls = WebActivity.class;
}
if (url.contains("leave_web_page_handle_back_pressed=true")) {
bundle.putBoolean(WebFragment.KEY_LEAVE_WEB_PAGE_TO_HANDLE_BACK_PRESSED, true);
}
Intent intent = new Intent(context, cls);
intent.putExtra(NormalActivity.NORMAL_FRAGMENT_NAME, WebFragment.class.getCanonicalName());

View File

@ -584,6 +584,27 @@ public class LogUtils {
.postShareResult(body)
.subscribeOn(Schedulers.io())
.subscribe(new EmptyResponse<>());
// 判断是否上报游戏单活动的"转发活动"任务
postGameCollectionRepostActivityTaskCheck(url, shareResult);
}
@SuppressLint("CheckResult")
public static void postGameCollectionRepostActivityTaskCheck(String url, String shareResult) {
if (!TextUtils.isEmpty(url) && "success".equals(shareResult)) {
String gameCollectionActivityUrl;
if (EnvHelper.isDevEnv()) {
gameCollectionActivityUrl = Constants.GAME_COLLECTION_ACTIVITY_ADDRESS_DEV;
} else {
gameCollectionActivityUrl = Constants.GAME_COLLECTION_ACTIVITY_ADDRESS;
}
if (url.contains(gameCollectionActivityUrl)) {
RetrofitManager.getInstance(HaloApp.getInstance().getApplication()).getNewApi()
.postGameCollectionTask("repost_activity", "0")
.subscribeOn(Schedulers.io())
.subscribe(new EmptyResponse<>());
}
}
}
public static JSONObject getMetaObject() {

View File

@ -69,7 +69,8 @@ object RealNameHelper {
}
val currentActivity = CurrentActivityHolder.getCurrentActivity()
if (currentActivity == null) {
if (currentActivity == null
|| currentActivity.isFinishing) {
ToastUtils.toast("为保护未成年身心健康成长,根据相关政策要求,该游戏不对未成年人开放")
} else {
NewLogUtils.logCertificationHintDialogAppearance()

View File

@ -17,50 +17,54 @@ public class CustomLinkMovementMethod extends LinkMovementMethod {
int action = event.getAction();
boolean isTouchEventConsumed = false;
if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) {
int x = (int) event.getX();
int y = (int) event.getY();
try {
if (action == MotionEvent.ACTION_UP || action == MotionEvent.ACTION_DOWN) {
int x = (int) event.getX();
int y = (int) event.getY();
x -= widget.getTotalPaddingLeft();
y -= widget.getTotalPaddingTop();
x -= widget.getTotalPaddingLeft();
y -= widget.getTotalPaddingTop();
x += widget.getScrollX();
y += widget.getScrollY();
x += widget.getScrollX();
y += widget.getScrollY();
Layout layout = widget.getLayout();
int line = layout.getLineForVertical(y);
int off = layout.getOffsetForHorizontal(line, x);
Layout layout = widget.getLayout();
int line = layout.getLineForVertical(y);
int off = layout.getOffsetForHorizontal(line, x);
ClickableSpan[] links = buffer.getSpans(off, off, ClickableSpan.class);
ClickableSpan[] links = buffer.getSpans(off, off, ClickableSpan.class);
if (links.length != 0) {
ClickableSpan link = links[0];
if (action == MotionEvent.ACTION_UP) {
link.onClick(widget);
} else if (action == MotionEvent.ACTION_DOWN) {
// 下面这行代码会造成触摸 clickbleSpan 时 RecyclerView 的 item 高度变更 : (
// 看起来像是跟文字选择相关的东西,反正我们的 clickSpan 也不让选,直接屏蔽掉了
if (links.length != 0) {
ClickableSpan link = links[0];
if (action == MotionEvent.ACTION_UP) {
link.onClick(widget);
} else if (action == MotionEvent.ACTION_DOWN) {
// 下面这行代码会造成触摸 clickbleSpan 时 RecyclerView 的 item 高度变更 : (
// 看起来像是跟文字选择相关的东西,反正我们的 clickSpan 也不让选,直接屏蔽掉了
// Selection.setSelection(buffer,
// buffer.getSpanStart(link),
// buffer.getSpanEnd(link));
}
isTouchEventConsumed = true;
} else {
Selection.removeSelection(buffer);
}
isTouchEventConsumed = true;
} else {
Selection.removeSelection(buffer);
}
}
//解决点击事件冲突问题
if (!isTouchEventConsumed && event.getAction() == MotionEvent.ACTION_UP) {
ViewParent parent = iterateViewParentForClicking(widget.getParent());//处理widget的父控件点击事件
if (parent instanceof ViewGroup) {
return ((ViewGroup) parent).performClick();
//解决点击事件冲突问题
if (!isTouchEventConsumed && event.getAction() == MotionEvent.ACTION_UP) {
ViewParent parent = iterateViewParentForClicking(widget.getParent());//处理widget的父控件点击事件
if (parent instanceof ViewGroup) {
return ((ViewGroup) parent).performClick();
}
}
} catch (ArrayIndexOutOfBoundsException e) {
e.printStackTrace();
}
return false;
}
private ViewParent iterateViewParentForClicking(ViewParent parent) {
if (parent instanceof ViewGroup) {
if (((ViewGroup) parent).hasOnClickListeners()) {

View File

@ -727,20 +727,20 @@ public class DWebView extends WebView {
}
Activity activity = (AppCompatActivity) getContext();
if (activity.isFinishing()) return true;
Dialog alertDialog = new AlertDialog.Builder(getContext()).
AlertDialog alertDialog = new AlertDialog.Builder(getContext()).
setMessage(message).
setCancelable(false).
setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
dialog.dismiss();
if (alertBoxBlock) {
result.confirm();
}
}
})
setPositiveButton(android.R.string.ok, null)
.create();
alertDialog.show();
alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(v -> {
if (!activity.isFinishing()) {
alertDialog.dismiss();
if (alertBoxBlock) {
result.confirm();
}
}
});
return true;
}
@ -755,23 +755,27 @@ public class DWebView extends WebView {
} else {
Activity activity = (AppCompatActivity) getContext();
if (activity.isFinishing()) return true;
DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (alertBoxBlock) {
if (which == Dialog.BUTTON_POSITIVE) {
result.confirm();
} else {
result.cancel();
}
}
}
};
new AlertDialog.Builder(getContext())
AlertDialog alertDialog = new AlertDialog.Builder(getContext())
.setMessage(message)
.setCancelable(false)
.setPositiveButton(android.R.string.ok, listener)
.setNegativeButton(android.R.string.cancel, listener).show();
.setPositiveButton(android.R.string.ok, null)
.setNegativeButton(android.R.string.cancel, null).show();
alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(v -> {
if (alertBoxBlock) {
result.confirm();
}
if (!activity.isFinishing()) {
alertDialog.dismiss();
}
});
alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE).setOnClickListener(v -> {
if (alertBoxBlock) {
result.cancel();
}
if (!activity.isFinishing()) {
alertDialog.dismiss();
}
});
return true;
}
@ -805,25 +809,29 @@ public class DWebView extends WebView {
editText.setSelection(defaultValue.length());
}
float dpi = getContext().getResources().getDisplayMetrics().density;
DialogInterface.OnClickListener listener = new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
if (alertBoxBlock) {
if (which == Dialog.BUTTON_POSITIVE) {
result.confirm(editText.getText().toString());
} else {
result.cancel();
}
}
}
};
new AlertDialog.Builder(getContext())
AlertDialog alertDialog = new AlertDialog.Builder(getContext())
.setTitle(message)
.setView(editText)
.setCancelable(false)
.setPositiveButton(android.R.string.ok, listener)
.setNegativeButton(android.R.string.cancel, listener)
.setPositiveButton(android.R.string.ok, null)
.setNegativeButton(android.R.string.cancel, null)
.show();
alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener(v -> {
if (alertBoxBlock) {
result.confirm(editText.getText().toString());
}
if (!activity.isFinishing()) {
alertDialog.dismiss();
}
});
alertDialog.getButton(AlertDialog.BUTTON_NEGATIVE).setOnClickListener(v -> {
if (alertBoxBlock) {
result.cancel();
}
if (!activity.isFinishing()) {
alertDialog.dismiss();
}
});
FrameLayout.LayoutParams layoutParams = new FrameLayout.LayoutParams(
ViewGroup.LayoutParams.MATCH_PARENT,
ViewGroup.LayoutParams.WRAP_CONTENT);

View File

@ -181,11 +181,11 @@ public class MainActivity extends BaseActivity {
protected void onCreate(Bundle savedInstanceState) {
showAd = getIntent().getBooleanExtra(SHOW_AD, false) && savedInstanceState == null;
HaloApp.getInstance().initFresco();
super.onCreate(savedInstanceState);
setStatusBarColor(Color.TRANSPARENT);
HaloApp.getInstance().initFresco();
Fragment fragmentFromFM = getSupportFragmentManager().findFragmentById(R.id.layout_activity_content);
mMainWrapperFragment = fragmentFromFM != null ? (MainWrapperFragment) fragmentFromFM : new MainWrapperFragment();
@ -200,7 +200,7 @@ public class MainActivity extends BaseActivity {
isNewFirstLaunch = mSp.getBoolean("isNewFirstLaunchV" + PackageUtils.getGhVersionName(), true);
if (isNewFirstLaunch) {
final LunchType lunchType = DeviceTokenUtils.getLaunchType();
final LunchType lunchType = DeviceTokenUtils.getLaunchType(false);
// 延时两秒提交,避免提交时还没获取到 GID/OAID
AppExecutor.getUiExecutor().executeWithDelay(() -> {
if (!this.isFinishing()) {
@ -235,21 +235,38 @@ public class MainActivity extends BaseActivity {
if (!TextUtils.isEmpty(message)) {
Config.setExceptionMsg(null);
AppUncaughtHandler.reportException(this, new Throwable(message));
DialogHelper.showCenterWarningDialog(this, "发生闪退", "光环助手刚刚发生了闪退,马上反馈以帮助我们更好地修复问题?(只需简单描述你刚才的操作)"
, "暂不", "马上反馈",
() -> {
startActivityForResult(SuggestionActivity.getIntent(MainActivity.this, SuggestType.crash, "APP闪退"), 100);
MtaHelper.onEventWithBasicDeviceInfo(
"闪退弹窗",
"玩家操作", "点击反馈");
return null;
},
() -> {
MtaHelper.onEventWithBasicDeviceInfo(
"闪退弹窗",
"玩家操作", "点击关闭");
return null;
});
// 被改过的包闪退时增加跳转到光环游戏详情并自动下载的方法
if (Config.DEFAULT_CHANNEL_FOR_RELEASE.equals(HaloApp.getInstance().getChannel())) {
DialogHelper.showCenterWarningDialog(this, "发生闪退", "光环助手发生了闪退,建议安装到最新版本修复异常"
, "马上反馈", "马上安装修复",
() -> {
DirectUtils.directToGameDetail(this, Constants.GHZS_GAME_ID, "crash", true, "desc", null);
return null;
},
() -> {
startActivityForResult(SuggestionActivity.getIntent(MainActivity.this, SuggestType.crash, "APP闪退"), 100);
MtaHelper.onEventWithBasicDeviceInfo(
"闪退弹窗",
"玩家操作", "点击反馈");
return null;
});
} else {
DialogHelper.showCenterWarningDialog(this, "发生闪退", "光环助手刚刚发生了闪退,马上反馈以帮助我们更好地修复问题?(只需简单描述你刚才的操作)"
, "暂不", "马上反馈",
() -> {
startActivityForResult(SuggestionActivity.getIntent(MainActivity.this, SuggestType.crash, "APP闪退"), 100);
MtaHelper.onEventWithBasicDeviceInfo(
"闪退弹窗",
"玩家操作", "点击反馈");
return null;
},
() -> {
MtaHelper.onEventWithBasicDeviceInfo(
"闪退弹窗",
"玩家操作", "点击关闭");
return null;
});
}
}
// checkTinkerPath(); // 看情况是否需要显示补丁弹窗

View File

@ -37,6 +37,7 @@ import static com.gh.common.util.EntranceUtils.HOST_COMMUNITY_QUESTION_LABEL_DET
import static com.gh.common.util.EntranceUtils.HOST_DOWNLOAD;
import static com.gh.common.util.EntranceUtils.HOST_GAME;
import static com.gh.common.util.EntranceUtils.HOST_GAME_COLLECTION_DETAIL;
import static com.gh.common.util.EntranceUtils.HOST_GAME_COLLECTION_SQUARE;
import static com.gh.common.util.EntranceUtils.HOST_LIBAO;
import static com.gh.common.util.EntranceUtils.HOST_QQ;
import static com.gh.common.util.EntranceUtils.HOST_QQ_GROUP;
@ -114,7 +115,8 @@ public class SkipActivity extends BaseActivity {
String platformName = PlatformUtils.getInstance(this).getPlatformName(platform);
String gameId = uri.getQueryParameter(EntranceUtils.KEY_GAMEID);
String packageMd5 = uri.getQueryParameter(EntranceUtils.KEY_PACKAGE_MD5);
boolean isQaFeedback = uri.getQueryParameter(EntranceUtils.KEY_IS_QA_FEEDBACK).equals("true");
String isQaFeedbackString = uri.getQueryParameter(EntranceUtils.KEY_IS_QA_FEEDBACK);
boolean isQaFeedback = !TextUtils.isEmpty(isQaFeedbackString) && isQaFeedbackString.equals("true");
String content = (TextUtils.isEmpty(gameId) || TextUtils.isEmpty(packageMd5)) ?
String.format("%s-%s-V%s",
uri.getQueryParameter(KEY_GAME_NAME),
@ -394,6 +396,9 @@ public class SkipActivity extends BaseActivity {
case HOST_GAME_COLLECTION_DETAIL:
DirectUtils.directToGameCollectionDetail(this, path, ENTRANCE_BROWSER);
break;
case HOST_GAME_COLLECTION_SQUARE:
DirectUtils.directToGameCollectionSquare(this, ENTRANCE_BROWSER, "", "", "");
break;
default:
EntranceUtils.jumpActivity(this, new Bundle()); // 跳转至首页
return;

View File

@ -295,7 +295,7 @@ public class SplashScreenActivity extends BaseActivity {
HaloApp.getInstance().setLocalTemporaryDeviceId(localTemporaryDeviceId);
SPUtils.setString(Constants.SP_TEMPORARY_DEVICE_ID, localTemporaryDeviceId);
}
map.put("launch_type", DeviceTokenUtils.getLaunchType().name());
map.put("launch_type", DeviceTokenUtils.getLaunchType(true).name());
} else if (HaloApp.getInstance().isReinstallTheSameVersion) {
map.put("launch_type", LunchType.UPDATE.toString());
}

View File

@ -348,14 +348,13 @@ public class SuggestionActivity extends ToolBarActivity implements OnRequestCall
if (cursor == null || !cursor.moveToFirst()) {
return;
}
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
cursor.close();
Utils.log("picturePath = " + picturePath);
try {
int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
String picturePath = cursor.getString(columnIndex);
cursor.close();
Utils.log("picturePath = " + picturePath);
File file = new File(picturePath);
if (file.length() > ImageUtils.getUploadFileMaxSize()) {
long count = ImageUtils.getUploadFileMaxSize() / 1024 / 1024;
@ -1292,7 +1291,8 @@ public class SuggestionActivity extends ToolBarActivity implements OnRequestCall
, "关闭提交", "返回修改", () -> {
setResult(SUGGEST_TYPE_REQUEST);
finish();
}, () -> { });
}, () -> {
});
return;
} else if (error.getCode() == 403062) {
DialogHelper.showCenterDialog(SuggestionActivity.this,
@ -1408,7 +1408,8 @@ public class SuggestionActivity extends ToolBarActivity implements OnRequestCall
intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");
startActivityForResult(intent, MEDIA_STORE_REQUEST);
}
}, () -> { });
}, () -> {
});
return;
}
List<String> picList = (List<String>) data;
@ -1458,7 +1459,8 @@ public class SuggestionActivity extends ToolBarActivity implements OnRequestCall
mFunctionType != -1) {
DialogHelper.showCenterDialog(this, "提示",
"确定放弃反馈吗?", "继续反馈", "放弃",
() -> { }, this::finish);
() -> {
}, this::finish);
return true;
}
return super.handleBackPressed();

View File

@ -51,21 +51,27 @@ public class CollectionWrapperFragment extends BaseFragment_TabLayout {
fragments.add(new AnswerFragment().with(getArguments()));
fragments.add(new CommunityArticleFragment().with(getArguments()));
Bundle arguments = getArguments();
if (arguments != null)
arguments.putString("videoStyle", VideoFragment.VideoStyle.COLLECT.getValue());
fragments.add(new VideoFragment().with(arguments));
Bundle gameCollectionArguments = getArguments();
if (gameCollectionArguments != null) {
gameCollectionArguments.putString(EntranceUtils.KEY_USER_ID, UserManager.getInstance().getUserId());
gameCollectionArguments.putString(EntranceUtils.KEY_TYPE, GamesCollectionFragment.TYPE_COLLECT);
Bundle videoArguments;
if (getArguments() != null) {
videoArguments = (Bundle) getArguments().clone();
} else {
videoArguments = new Bundle();
}
fragments.add(new GamesCollectionFragment().with(arguments));
videoArguments.putString("videoStyle", VideoFragment.VideoStyle.COLLECT.getValue());
fragments.add(new VideoFragment().with(videoArguments));
Bundle gameCollectionArguments;
if (getArguments() != null) {
gameCollectionArguments = (Bundle) getArguments().clone();
} else {
gameCollectionArguments = new Bundle();
}
gameCollectionArguments.putString(EntranceUtils.KEY_USER_ID, UserManager.getInstance().getUserId());
gameCollectionArguments.putString(EntranceUtils.KEY_TYPE, GamesCollectionFragment.TYPE_COLLECT);
fragments.add(new GamesCollectionFragment().with(gameCollectionArguments));
fragments.add(new ToolsFragment().with(getArguments()));
fragments.add(new ArticleFragment().with(getArguments()));
}
@Override

View File

@ -25,7 +25,6 @@ class InstalledGameViewModel(application: Application) : AndroidViewModel(applic
val gameListLiveData = MutableLiveData<ArrayList<GameEntity>>()
private val sortedList: ArrayList<GameInstall> = ArrayList()
private val gameList: ArrayList<GameEntity> = ArrayList()
var isRemove = false
val locationMap: ArrayMap<String, ArrayList<Int>> = ArrayMap()
@ -47,7 +46,6 @@ class InstalledGameViewModel(application: Application) : AndroidViewModel(applic
}
}
sortedList.clear()
gameList.clear()
sortedList.addAll(list)
if (sortedList.isNotEmpty()) {
val ids = ArrayList<String>()
@ -56,12 +54,16 @@ class InstalledGameViewModel(application: Application) : AndroidViewModel(applic
0
} else {
// 按安装时间排序
if (rhs.installTime > lhs.installTime) {
1
} else if (rhs.installTime < lhs.installTime) {
-1
} else {
0
when {
rhs.installTime > lhs.installTime -> {
1
}
rhs.installTime < lhs.installTime -> {
-1
}
else -> {
0
}
}
}
}
@ -74,7 +76,7 @@ class InstalledGameViewModel(application: Application) : AndroidViewModel(applic
}
initGameList(ids)
} else {
gameListLiveData.postValue(gameList)
gameListLiveData.postValue(ArrayList())
}
}
@ -151,16 +153,14 @@ class InstalledGameViewModel(application: Application) : AndroidViewModel(applic
entity.setEntryMap(DownloadManager.getInstance(getApplication()).getEntryMap(entity.name))
}
}
this.gameList.clear()
this.gameList.addAll(newGameList)
if (this.gameList.isNotEmpty()){
if (newGameList.isNotEmpty()){
isRemove = true
initLocationMap()
initLocationMap(newGameList)
}
gameListLiveData.postValue(this.gameList)
gameListLiveData.postValue(newGameList)
}
private fun initLocationMap() {
private fun initLocationMap(gameList: List<GameEntity>) {
locationMap.clear()
var list: ArrayList<Int>?
for (i in gameList.indices) {

View File

@ -46,8 +46,9 @@ class NewInstalledGameFragment : NormalFragment() {
private val dataWatcher = object : DataWatcher() {
override fun onDataChanged(downloadEntity: DownloadEntity) {
if (downloadEntity.status == DownloadStatus.done && downloadEntity.isSimulatorGame()) {
DownloadManager.getInstance(requireContext())
.getEntryMap(downloadEntity.name)[downloadEntity.platform] = downloadEntity
DownloadManager.getInstance(requireContext()).getEntryMap(downloadEntity.name)?.let {
it[downloadEntity.platform] = downloadEntity
}
mPackageViewModel?.getGameInstalledLiveData()?.value?.let {
mInstallGameViewModel.initData(
PackagesManager.filterSameApk(
@ -103,7 +104,7 @@ class NewInstalledGameFragment : NormalFragment() {
mBinding.fmInstallRvShow.addItemDecoration(
VerticalItemDecoration(
requireContext(),
8f,
8F,
true
)
)
@ -123,6 +124,8 @@ class NewInstalledGameFragment : NormalFragment() {
mInstallGameViewModel.gameListLiveData.observe(this, {
mSkeleton?.hide()
if (!it.isNullOrEmpty()) {
mBinding.fmInstallRvShow.visibility = View.VISIBLE
mBinding.reuseNodataSkip.reuseNodataSkip.visibility = View.GONE
mAdapter?.submitList(it)
} else {
mBinding.fmInstallRvShow.visibility = View.GONE
@ -137,7 +140,7 @@ class NewInstalledGameFragment : NormalFragment() {
override fun onResume() {
super.onResume()
val gameList = mInstallGameViewModel.gameListLiveData.value
if (isEverpause && gameList != null) {
if (isEverpause && !gameList.isNullOrEmpty()) {
for (entity in gameList) {
entity.setEntryMap(
DownloadManager.getInstance(requireContext()).getEntryMap(entity.name)
@ -145,6 +148,13 @@ class NewInstalledGameFragment : NormalFragment() {
}
mInstallGameViewModel.gameListLiveData.postValue(gameList)
}
if (isEverpause) {
mInstallGameViewModel.initData(
PackagesManager.filterSameApk(
PackagesManager.filterDownloadBlackPackage(mPackageViewModel?.getGameInstalledLiveData()?.value as MutableList<GameInstall>?)
)
)
}
isEverpause = false
DownloadManager.getInstance(requireContext()).addObserver(dataWatcher)
}

View File

@ -82,7 +82,7 @@ class UpdatableGameViewModel(
}
}
mUpdatableItemDataList.clear()
// mUpdatableItemDataList.clear()
sortUpdatableListByType(mRawUpdatableList)

View File

@ -140,7 +140,7 @@ class ForumDetailViewModel(application: Application, val bbsId: String) : Androi
answerEntity.images = articleDetailEntity.images
answerEntity.imagesInfo = articleDetailEntity.imagesInfo
answerEntity.videos = articleDetailEntity.videos
answerEntity.status = articleDetailEntity.status
answerEntity.status = articleDetailEntity.status ?:""
answerEntity.type = "community_article"
return answerEntity

View File

@ -132,7 +132,7 @@ class CommunityHomeFragment : BaseLazyFragment() {
2 -> {
NewLogUtils.logCommunityHomeEvent("click_activity_tab")
FloatingBackViewManager.disableBackView()
FloatingBackViewManager.dismissBackView(requireActivity())
FloatingBackViewManager.dismissBackView()
}
}
},

View File

@ -18,39 +18,39 @@ class CommunityHomeViewModel(application: Application) : AndroidViewModel(applic
fun getArticleData(communityId: String, articleId: String) {
mApi.getCommunityArticleDetail(communityId, articleId)
.compose(observableToMain())
.subscribe(object : Response<ArticleDetailEntity>() {
override fun onResponse(response: ArticleDetailEntity?) {
response?.run {
articleLiveData.postValue(convertArticleDetailToArticle(response))
}
.compose(observableToMain())
.subscribe(object : Response<ArticleDetailEntity>() {
override fun onResponse(response: ArticleDetailEntity?) {
response?.run {
articleLiveData.postValue(convertArticleDetailToArticle(response))
}
})
}
})
}
fun getQuestionDetail(questionId: String) {
mApi.getQuestionsById(questionId)
.compose(observableToMain())
.subscribe(object : Response<QuestionsDetailEntity>() {
override fun onResponse(response: QuestionsDetailEntity?) {
response?.run {
articleLiveData.postValue(convertQuestionDetailToArticle(response))
}
.compose(observableToMain())
.subscribe(object : Response<QuestionsDetailEntity>() {
override fun onResponse(response: QuestionsDetailEntity?) {
response?.run {
articleLiveData.postValue(convertQuestionDetailToArticle(response))
}
})
}
})
}
fun getVideoDetail(videoId: String) {
mApi.getBbsVideoDetail(videoId)
.compose(observableToMain())
.subscribe(object : Response<ForumVideoEntity>() {
override fun onResponse(response: ForumVideoEntity?) {
response?.run {
articleLiveData.postValue(convertVideoDetailToArticle(response))
}
.compose(observableToMain())
.subscribe(object : Response<ForumVideoEntity>() {
override fun onResponse(response: ForumVideoEntity?) {
response?.run {
articleLiveData.postValue(convertVideoDetailToArticle(response))
}
})
}
})
}
fun convertArticleDetailToArticle(articleDetailEntity: ArticleDetailEntity): ArticleEntity {
@ -68,7 +68,7 @@ class CommunityHomeViewModel(application: Application) : AndroidViewModel(applic
articleEntity.images = articleDetailEntity.images
articleEntity.imagesInfo = articleDetailEntity.imagesInfo
articleEntity.videos = articleDetailEntity.videos
articleEntity.status = articleDetailEntity.status
articleEntity.status = articleDetailEntity.status ?: ""
articleEntity.type = "community_article"
return articleEntity
@ -111,12 +111,13 @@ class CommunityHomeViewModel(application: Application) : AndroidViewModel(applic
articleEntity.title = forumVideoEntity.title
forumVideoEntity.user.run {
articleEntity.user = UserEntity(
id = id,
name = name,
icon = icon,
auth = auth,
badge = badge,
border = border)
id = id,
name = name,
icon = icon,
auth = auth,
badge = badge,
border = border
)
}
articleEntity.type = "video"

View File

@ -496,7 +496,7 @@ public class MainWrapperFragment extends BaseFragment_ViewPager_Checkable implem
if (index != INDEX_BBS) {
FloatingBackViewManager.disableBackView();
FloatingBackViewManager.dismissBackView(requireActivity());
FloatingBackViewManager.dismissBackView();
}
SubjectRecommendEntity navBarEntity = mViewModel.getNavBar().getValue();

View File

@ -460,13 +460,13 @@ class GameUploadFragment : NormalFragment() {
?: return
cursor.moveToFirst()
val columnIndex = cursor.getColumnIndex(filePathColumn[0])
val picturePath = cursor.getString(columnIndex)
cursor.close()
Utils.log("picturePath = $picturePath")
try {
val columnIndex = cursor.getColumnIndex(filePathColumn[0])
val picturePath = cursor.getString(columnIndex)
cursor.close()
Utils.log("picturePath = $picturePath")
val file = File(picturePath)
if (file.length() > 5 * 1024 * 1024) {
ToastUtils.showToast(getString(R.string.pic_max_hint, 5))

View File

@ -40,9 +40,20 @@ class ChooseGamesAdapter(context: Context, val dragListener: ItemDragListener) :
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if (holder is ChooseGamesViewHolder) {
val gameEntity = mEntityList[position]
holder.binding.root.tag = gameEntity.id
holder.binding.gameNameTv.text = gameEntity.name
holder.binding.gameIcon.displayGameIcon(gameEntity)
holder.binding.recommendReasonEt.setText(gameEntity.recommendText)
holder.binding.ratingScore.rating = gameEntity.recommendStar.toFloat()
holder.binding.recommendReasonEt.filters = arrayOf(TextHelper.getFilter(45, "最多输入45个字"))
holder.binding.recommendReasonEt.doOnTextChanged { text, _, _, _ ->
if (holder.binding.root.tag != gameEntity.id) return@doOnTextChanged
gameEntity.recommendText = text.toString()
}
holder.binding.recommendReasonEt.run {
doOnTextChanged { text, start, _, _ ->
if(PatternUtils.isHasWrap(text.toString())){
if (holder.binding.root.tag != gameEntity.id) return@doOnTextChanged
if (PatternUtils.isHasWrap(text.toString())) {
setText(PatternUtils.replaceWrap(text.toString()))
setSelection(start)
return@doOnTextChanged
@ -54,15 +65,8 @@ class ChooseGamesAdapter(context: Context, val dragListener: ItemDragListener) :
}
}
}
holder.binding.gameNameTv.text = gameEntity.name
holder.binding.gameIcon.displayGameIcon(gameEntity)
holder.binding.recommendReasonEt.setText(gameEntity.recommendText)
holder.binding.ratingScore.rating = gameEntity.recommendStar.toFloat()
holder.binding.recommendReasonEt.filters = arrayOf(TextHelper.getFilter(45, "最多输入45个字"))
holder.binding.recommendReasonEt.doOnTextChanged { text, _, _, _ ->
gameEntity.recommendText = text.toString()
}
holder.binding.ratingScore.setOnRatingChangeListener { _, rating ->
if (holder.binding.root.tag != gameEntity.id) return@setOnRatingChangeListener
gameEntity.recommendStar = rating.toInt()
}
holder.binding.deleteIv.setOnClickListener {

View File

@ -5,8 +5,10 @@ import android.content.Intent
import android.os.Bundle
import com.gh.common.util.DisplayUtils
import com.gh.common.util.EntranceUtils
import com.gh.common.util.GameCollectionSquareBrowseTaskHelper
import com.gh.gamecenter.NormalActivity
import com.gh.gamecenter.R
import com.gh.gamecenter.gamecollection.square.GameCollectionSquareActivity
class GameCollectionDetailActivity : NormalActivity() {
@ -32,6 +34,10 @@ class GameCollectionDetailActivity : NormalActivity() {
bundle.putString(EntranceUtils.KEY_GAME_COLLECTION_ID, gameCollectionId)
bundle.putBoolean(EntranceUtils.KEY_IS_FROM_SQUARE, isFromSquare)
bundle.putBoolean(EntranceUtils.KEY_SCROLL_TO_COMMENT_AREA, isScrollToCommentArea)
if (context is GameCollectionSquareActivity) {
val isFromBrowseTask = context.intent.getBooleanExtra(GameCollectionSquareBrowseTaskHelper.KEY_IS_FORM_BROWSE_TASK, false)
bundle.putBoolean(GameCollectionSquareBrowseTaskHelper.KEY_IS_FORM_BROWSE_TASK, isFromBrowseTask)
}
return getTargetIntent(context, GameCollectionDetailActivity::class.java, GameCollectionDetailFragment::class.java, bundle)
}
}

View File

@ -19,7 +19,6 @@ import com.gh.common.syncpage.SyncDataEntity
import com.gh.common.syncpage.SyncFieldConstants
import com.gh.common.syncpage.SyncPageRepository
import com.gh.common.util.*
import com.gh.common.view.vertical_recycler.SnappingLinearLayoutManager
import com.gh.common.xapk.XapkInstaller
import com.gh.common.xapk.XapkUnzipStatus
import com.gh.download.DownloadManager
@ -72,6 +71,7 @@ class GameCollectionDetailFragment :
private var mIsPauseTopVideo = false
private var mOrientationUtils: OrientationUtils? = null
private var mStopUpdateToolbar = false
private var mIsViewGameCollectionFinished = false // 是否已经完成"浏览游戏单"浏览至少2s
private val mDataWatcher = object : DataWatcher() {
override fun onDataChanged(downloadEntity: DownloadEntity) {
mAdapter?.notifyItemByDownload(downloadEntity)
@ -159,11 +159,17 @@ class GameCollectionDetailFragment :
HistoryHelper.deleteGamesCollectionEntity(mGameCollectionId)
}
postDelayedRunnable({
tryCatchInRelease {
logEvent("view_game_collect_detail")
}
}, 2000)
if (!mIsViewGameCollectionFinished) {
postDelayedRunnable({
tryCatchInRelease {
if (!isEverPause && !mIsViewGameCollectionFinished) {
mIsViewGameCollectionFinished = true
logEvent("view_game_collect_detail")
mListViewModel.postGameCollectionTask("browse_game_list", mGameCollectionId)
}
}
}, 2000)
}
updateView()
initViewListener()
@ -643,6 +649,18 @@ class GameCollectionDetailFragment :
if (!mIsPauseTopVideo) {
resumeVideo()
}
if (!mIsViewGameCollectionFinished && mEntity != null) {
postDelayedRunnable({
tryCatchInRelease {
if (!isEverPause && !mIsViewGameCollectionFinished) {
mIsViewGameCollectionFinished = true
logEvent("view_game_collect_detail")
mListViewModel.postGameCollectionTask("browse_game_list", mGameCollectionId)
}
}
}, 2000)
}
}
override fun onPause() {

View File

@ -22,6 +22,7 @@ import com.gh.gamecenter.manager.UserManager
import com.gh.gamecenter.qa.article.detail.CommentItemData
import com.gh.gamecenter.qa.comment.base.BaseCommentViewModel
import com.gh.gamecenter.retrofit.BiResponse
import com.gh.gamecenter.retrofit.EmptyResponse
import com.gh.gamecenter.retrofit.Response
import com.gh.gamecenter.retrofit.RetrofitManager
import com.halo.assistant.HaloApp
@ -258,6 +259,8 @@ open class GameCollectionDetailViewModel(application: Application,
@SuppressLint("CheckResult")
fun postShareGameCollection() {
postGameCollectionTask("forward_share_game_list")
if (gameCollectionDetail == null) return
mApi.shareGameCollection(gameCollectionId)
.compose(singleToMain())
@ -361,6 +364,15 @@ open class GameCollectionDetailViewModel(application: Application,
})
}
@SuppressLint("CheckResult")
fun postGameCollectionTask(event: String, gameCollectionId: String = "0") {
RetrofitManager.getInstance(HaloApp.getInstance())
.newApi
.postGameCollectionTask(event, gameCollectionId)
.compose(singleToMain())
.subscribe(EmptyResponse())
}
fun getStarText(): String {
val favoriteCount = gameCollectionDetail?.count?.favorite ?: 0
return when {

View File

@ -22,7 +22,7 @@ class GameCollectionAmwayAdapter(context: Context) :
override fun onCreateViewHolder(parent: ViewGroup, viewType: Int) =
GameCollectionAmwayContentItemViewHolder(GameCollectionAmwayContentItemBinding.inflate(mLayoutInflater, parent, false))
override fun getItemCount() = if (getRealCount() > 1) getRealCount() + INCREASE_COUNT else getRealCount()
override fun getItemCount() = Int.MAX_VALUE
override fun onBindViewHolder(holder: RecyclerView.ViewHolder, position: Int) {
if (holder is GameCollectionAmwayContentItemViewHolder) {
@ -34,21 +34,7 @@ class GameCollectionAmwayAdapter(context: Context) :
class GameCollectionAmwayContentItemViewHolder(var binding: GameCollectionAmwayContentItemBinding) :
RecyclerView.ViewHolder(binding.root)
fun getRealCount(): Int = mAmwayList.size
fun getRealCount() = mAmwayList.size
fun getRealPosition(position: Int) = when (position) {
0 -> {
getRealCount() - 1
}
getRealCount() + 1 -> {
0
}
else -> {
position - 1
}
}
companion object{
const val INCREASE_COUNT = 2
}
fun getRealPosition(position: Int) = position % getRealCount()
}

View File

@ -21,7 +21,7 @@ class GameCollectionAmwayViewHolder(var binding: GameCollectionSquareAmwayItemBi
if (vp != null) {
val count = mAdapter.itemCount
if (count == 0) return
val next = (vp.currentItem + 1) % count
val next = vp.currentItem + 1
vp.setCurrentItem(next, 1000)
vp.postDelayed(this, AMWAY_LOOP_TIME)
}
@ -35,34 +35,6 @@ class GameCollectionAmwayViewHolder(var binding: GameCollectionSquareAmwayItemBi
isUserInputEnabled = false
adapter = mAdapter
orientation = ViewPager2.ORIENTATION_VERTICAL
registerOnPageChangeCallback(object : ViewPager2.OnPageChangeCallback() {
private var mTempPosition = INVALID_VALUE
private var isScrolled = false
override fun onPageSelected(position: Int) {
if (isScrolled) {
mTempPosition = position
}
}
override fun onPageScrollStateChanged(state: Int) {
//手势滑动中,代码执行滑动中
if (state == ViewPager2.SCROLL_STATE_DRAGGING || state == ViewPager2.SCROLL_STATE_SETTLING) {
isScrolled = true
} else if (state == ViewPager2.SCROLL_STATE_IDLE) {
//滑动闲置或滑动结束
isScrolled = false
if (mTempPosition != INVALID_VALUE) {
if (mTempPosition == 0) {
setCurrentItem(mAdapter.getRealCount(), false)
} else if (mTempPosition == mAdapter.itemCount - 1) {
setCurrentItem(1, false)
}
}
}
}
})
setCurrentItem(1, false)
postDelayed(mLoopTask, AMWAY_LOOP_TIME)
}
binding.root.setOnClickListener {
@ -110,6 +82,5 @@ class GameCollectionAmwayViewHolder(var binding: GameCollectionSquareAmwayItemBi
companion object {
// 安利墙卡片轮播时间
const val AMWAY_LOOP_TIME = 5000L
const val INVALID_VALUE = -1
}
}

View File

@ -3,6 +3,7 @@ package com.gh.gamecenter.gamecollection.square
import android.os.Bundle
import com.gh.base.BaseActivity
import com.gh.common.util.DisplayUtils
import com.gh.common.util.GameCollectionSquareBrowseTaskHelper
import com.gh.gamecenter.R
class GameCollectionSquareActivity : BaseActivity() {
@ -20,4 +21,14 @@ class GameCollectionSquareActivity : BaseActivity() {
?: GameCollectionSquareFragment().with(intent.extras)
supportFragmentManager.beginTransaction().replace(R.id.placeholder, containerFragment, GameCollectionSquareFragment::class.java.simpleName).commitAllowingStateLoss()
}
override fun finish() {
GameCollectionSquareBrowseTaskHelper.run {
if (intent.getBooleanExtra(KEY_IS_FORM_BROWSE_TASK, false)){
disableBrowseTimeCount()
unregisterActivityLifecycleCallbacks()
}
}
super.finish()
}
}

View File

@ -7,7 +7,6 @@ import android.os.Bundle
import android.view.View
import android.view.ViewGroup
import android.view.animation.AnimationUtils
import android.view.animation.TranslateAnimation
import android.widget.ImageView
import android.widget.RelativeLayout
import android.widget.TextView

View File

@ -24,16 +24,16 @@ class HistoryWrapperFragment : BaseFragment_TabLayout() {
override fun initFragmentList(fragments: MutableList<Fragment>) {
fragments.add(HistoryGameListFragment().with(arguments))
fragments.add(GamesCollectionFragment().with(arguments?.apply {
fragments.add(GamesCollectionFragment().with((arguments?.clone() as? Bundle)?.apply {
putString(EntranceUtils.KEY_USER_ID, UserManager.getInstance().userId)
putString(EntranceUtils.KEY_TYPE, GamesCollectionFragment.TYPE_HISTORY)
}))
fragments.add(VideoFragment().with(arguments?.apply {
fragments.add(VideoFragment().with((arguments?.clone() as? Bundle)?.apply {
putString("videoStyle", VideoFragment.VideoStyle.BROWSING_HISTORY.value)
}))
fragments.add(AnswerFragment().with(arguments?.apply { putString(EntranceUtils.KEY_TYPE, AnswerFragment.HISTORY) }))
fragments.add(CommunityArticleFragment().with(arguments?.apply { putString(EntranceUtils.KEY_TYPE, CommunityArticleFragment.Type.HISTORY.value) }))
fragments.add(ArticleFragment().with(arguments?.apply { putString(EntranceUtils.KEY_TYPE, ArticleFragment.HISTORY) }))
fragments.add(AnswerFragment().with((arguments?.clone() as? Bundle)?.apply { putString(EntranceUtils.KEY_TYPE, AnswerFragment.HISTORY) }))
fragments.add(CommunityArticleFragment().with((arguments?.clone() as? Bundle)?.apply { putString(EntranceUtils.KEY_TYPE, CommunityArticleFragment.Type.HISTORY.value) }))
fragments.add(ArticleFragment().with((arguments?.clone() as? Bundle)?.apply { putString(EntranceUtils.KEY_TYPE, ArticleFragment.HISTORY) }))
}
override fun onPageSelected(position: Int) {

View File

@ -125,7 +125,7 @@ class HomeSlideListViewHolder(
}
lastStatePosition = curPosition
lastScrollState = scrollState
updateImmersiveColor(slideList[curPosition].placeholderColor.hexStringToIntColor())
updateImmersiveColor(slideList.safelyGetInRelease(curPosition)?.placeholderColor?.hexStringToIntColor() ?: Color.WHITE)
} else if (scrollState == RecyclerView.SCROLL_STATE_DRAGGING) {
lastScrollState = scrollState
}

View File

@ -54,17 +54,21 @@ class MyGameActivity : BaseActivity_TabLayout() {
private fun showGuide() {
AppExecutor.uiExecutor.executeWithDelay({
if (!SPUtils.getBoolean(Constants.SP_MY_GAME_GUIDE)) {
val binding = PopupMyGameGuideBinding.inflate(layoutInflater, null, false)
val popupWindow = BugFixedPopupWindow(binding.root, LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT)
binding.root.setOnClickListener {
SPUtils.setBoolean(Constants.SP_MY_GAME_GUIDE, true)
popupWindow.dismiss()
}
popupWindow.run {
isTouchable = true
isFocusable = true
showAtLocation(window.decorView, Gravity.TOP, 0, 0)
tryCatchInRelease {
if (!SPUtils.getBoolean(Constants.SP_MY_GAME_GUIDE)) {
val binding = PopupMyGameGuideBinding.inflate(layoutInflater, null, false)
val popupWindow = BugFixedPopupWindow(binding.root, LinearLayout.LayoutParams.MATCH_PARENT, LinearLayout.LayoutParams.MATCH_PARENT)
binding.root.setOnClickListener {
SPUtils.setBoolean(Constants.SP_MY_GAME_GUIDE, true)
popupWindow.dismiss()
}
popupWindow.run {
isTouchable = true
isFocusable = true
if (!isFinishing) {
showAtLocation(window.decorView, Gravity.TOP, 0, 0)
}
}
}
}
}, 500)

View File

@ -33,12 +33,12 @@ class ArticleDetailContentViewHolder(
binding.run {
richEditor.setInputEnabled(false)
richEditor.setPadding(16, 4, 16, 4)
richEditor.addJavascriptInterface(JsInterface(article.status), "imagelistener")
richEditor.addJavascriptInterface(JsInterface(article.status ?: ""), "imagelistener")
richEditor.addJavascriptInterface(
OnLinkClickListener(
root.context,
article.title,
article.status,
article.status ?: "",
mEntrance,
"帖子详情"
), "OnLinkClickListener"

View File

@ -576,11 +576,11 @@ abstract class BaseCommentAdapter(
if (itemDecorationCount == 0) {
addItemDecoration(GridSpacingItemColorDecoration(context, 2, R.color.white))
}
visibility = View.VISIBLE
}
} else {
(binding.commentPictureRv.adapter as CommentPictureAdapter).checkResetData(comment.images!!)
}
binding.commentPictureRv.visibility = View.VISIBLE
} else {
binding.commentPictureRv.visibility = View.GONE
}

View File

@ -33,20 +33,20 @@ data class ArticleDetailEntity(
var tagActivityId: String = "",
@SerializedName("tag_activity_name")
var tagActivityName: String = "",
var type: String = "",
var type: String? = "",
@SerializedName("game")
var gameEntity: GameEntity? = null,
@SerializedName("choiceness_status")
var choicenessStatus: String = "",// 精选状态 apply申请, pass already已精选 cancel not_yet未精选
var status: String = "pass",//pass通过fail未通过pending审核中
var original: String = ""
var choicenessStatus: String? = "",// 精选状态 apply申请, pass already已精选 cancel not_yet未精选
var status: String? = "pass",//pass通过fail未通过pending审核中
var original: String? = ""
) : Parcelable {
fun getSimplifyChoicenessStatus(): String {
return when (choicenessStatus) {
"already" -> "pass"
"not_yet" -> "cancel"
else -> choicenessStatus
else -> choicenessStatus ?: ""
}
}
}

View File

@ -109,6 +109,7 @@ class VideoCommentFragment : LazyListFragment<CommentItemData, VideoCommentViewM
}
fun startCommentActivity() {
if (!isSupportVisible) return
clickToastByStatus(mListViewModel.videoDetail?.status ?: "") {
mListViewModel.videoDetail?.let {
val intent = CommentActivity.getVideoCommentIntent(

View File

@ -149,7 +149,7 @@ class VideoDescTopViewHolder(
//若标题未超过一行或无描述内容、活动标签、原创标签,箭头不显示
val ellipsisCount =
binding.titleTv.layout.getEllipsisCount(binding.titleTv.lineCount - 1)
binding.titleTv.layout?.getEllipsisCount(binding.titleTv.lineCount - 1) ?: 0
binding.expandMoreIv.goneIf(entity.des.isEmpty() && entity.tagActivityName.isEmpty() && entity.original != "yes" && ellipsisCount == 0)
}
binding.expandMoreIv.setOnClickListener {

View File

@ -6,7 +6,6 @@ import com.chuckerteam.chucker.api.ChuckerCollector;
import com.chuckerteam.chucker.api.ChuckerInterceptor;
import com.chuckerteam.chucker.api.RetentionManager;
import com.gh.common.constant.Config;
import com.gh.common.util.EnvHelper;
import com.gh.gamecenter.Injection;
import com.gh.gamecenter.retrofit.service.ApiService;
@ -32,6 +31,7 @@ public class RetrofitManager {
private static final byte[] LOCK = new byte[0];
private final ApiService mApiService;
private final ApiService mUploadApiService;
private final ApiService mNewApiService;
public static <T> T provideService(OkHttpClient client, String url, Class<T> serviceCls) {
return new Retrofit.Builder()
@ -45,6 +45,7 @@ public class RetrofitManager {
OkHttpClient okHttpNormalConfig = getOkHttpConfig(context, 0, 2);
mApiService = provideService(okHttpNormalConfig, Config.API_HOST, ApiService.class);
mUploadApiService = provideService(getOkHttpConfig(context, UPLOAD_CALL_TIME_OUT, 1), Config.API_HOST, ApiService.class);
mNewApiService = provideService(okHttpNormalConfig, Config.NEW_API_HOST, ApiService.class);
}
private OkHttpClient getOkHttpConfig(Context context, int callTimeout, int maxRetryCount) {
@ -81,4 +82,8 @@ public class RetrofitManager {
public ApiService getUploadApi() {
return mUploadApiService;
}
public ApiService getNewApi() {
return mNewApiService;
}
}

View File

@ -3426,4 +3426,10 @@ public interface ApiService {
*/
@DELETE("api_go/game_list/{game_list_id}/comment/{comment_id}")
Observable<ResponseBody> deleteGameCollectionComment(@Path("game_list_id") String gameCollectionId, @Path("comment_id") String commentId);
/**
* 游戏单活动上报任务
*/
@POST("lottery/incr-progress/{task_event}/{game_list_id}")
Single<ResponseBody> postGameCollectionTask(@Path("task_event") String event, @Path("game_list_id") String gameCollectionId);
}

View File

@ -5,9 +5,7 @@ import android.view.ViewGroup
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.core.content.ContextCompat
import com.gh.base.BaseRecyclerViewHolder
import com.gh.common.util.dip2px
import com.gh.common.util.toColor
import com.gh.common.util.toDrawable
import com.gh.common.util.*
import com.gh.gamecenter.R
import com.gh.gamecenter.databinding.SearchDefaultHotItemBinding
import com.gh.gamecenter.entity.SettingsEntity
@ -40,10 +38,11 @@ class SearchDefaultHotAdapter(
if (!name.isSelected) {
name.postDelayed({ name.isSelected = true }, 500)
}
val drawableRes = "ic_search_no_${position + 1}"
val drawableId =
mContext.resources.getIdentifier(drawableRes, "drawable", mContext.packageName)
index.setImageDrawable(drawableId.toDrawable())
tryWithDefaultCatch {
val drawableRes = "ic_search_no_${position + 1}"
val drawableId = mContext.resources.getIdentifier(drawableRes, "drawable", mContext.packageName)
index.setImageDrawable(drawableId.toDrawable())
}
val textColor = when (position) {
0 -> R.color.text_ff5151.toColor()
1 -> R.color.text_F67722.toColor()

View File

@ -15,9 +15,12 @@ import androidx.collection.ArrayMap;
import androidx.lifecycle.ProcessLifecycleOwner;
import androidx.multidex.MultiDexApplication;
import com.facebook.animated.giflite.GifDecoder;
import com.facebook.imageformat.DefaultImageFormats;
import com.facebook.imagepipeline.core.ImagePipelineConfig;
import com.facebook.imagepipeline.core.ImageTranscoderType;
import com.facebook.imagepipeline.core.MemoryChunkType;
import com.facebook.imagepipeline.decoder.ImageDecoderConfig;
import com.gh.base.GlobalActivityLifecycleObserver;
import com.gh.common.AppExecutor;
import com.gh.common.FixedRateJobHelper;
@ -25,6 +28,7 @@ import com.gh.common.constant.Config;
import com.gh.common.constant.Constants;
import com.gh.common.exposure.ExposureManager;
import com.gh.common.filter.RegionSettingHelper;
import com.gh.common.image.EmptyDecoder;
import com.gh.common.loghub.LoghubUtils;
import com.gh.common.tracker.Tracker;
import com.gh.common.util.DataUtils;
@ -359,21 +363,36 @@ public class HaloApp extends MultiDexApplication {
// 会出现找不到 arm64 so 的情况,具体可见
// https://sentry.ghzs.com/organizations/lightgame/issues/53107/
// 所以这里尝试在 5.0 & 5.1 设备上关闭 fresco 的 native 解码,应该会让 5.0 & 5.1 的设备 OOM 概率提高,但先试试效果
// 效果不好,还是有闪退,麻了,见 https://sentry.ghzs.com/organizations/lightgame/issues/86665/
// 难道非得换成不用 SO 的 Glide ?
// 同时禁用动图
ImagePipelineConfig.Builder pipelineConfigBuilder = ImagePipelineConfig.newBuilder(this);
ImageDecoderConfig.Builder decodeConfigBuilder = ImageDecoderConfig.newBuilder();
// ImagePipelineConfig.Builder configBuilder = ImagePipelineConfig.newBuilder(this);
if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP
|| Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP_MR1) {
pipelineConfigBuilder.setMemoryChunkType(MemoryChunkType.BUFFER_MEMORY)
.setImageTranscoderType(ImageTranscoderType.JAVA_TRANSCODER);
decodeConfigBuilder.overrideDecoder(DefaultImageFormats.GIF, new GifDecoder()).build();
// if (Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP
// || Build.VERSION.SDK_INT == Build.VERSION_CODES.LOLLIPOP_MR1) {
// configBuilder.setMemoryChunkType(MemoryChunkType.BUFFER_MEMORY)
// .setImageTranscoderType(ImageTranscoderType.JAVA_TRANSCODER)
// .experiment()
// .setNativeCodeDisabled(true);
// }
String manufacture = Build.MANUFACTURER.toLowerCase();
// OPPO 和 VIVO 的 5.1.1 设备还会去加载 WEBP_ANIMATED 的 SO
// 实测没有发现有地方使用 WEBP_ANIMATED 的图片,这里用空占位图来替换 WEBP 动图
if ("oppo".equals(manufacture) || "vivo".equals(manufacture)) {
decodeConfigBuilder.overrideDecoder(DefaultImageFormats.WEBP_ANIMATED, new EmptyDecoder()).build();
}
pipelineConfigBuilder
.setImageDecoderConfig(decodeConfigBuilder.build())
.experiment()
.setNativeCodeDisabled(true);
// 图片仅加载静态图片
ImageUtils.disableAnimatedImage();
}
try {
BigImageViewer.initialize(FrescoImageLoader.with(this));
BigImageViewer.initialize(FrescoImageLoader.with(this, pipelineConfigBuilder.build()));
} catch (Throwable e) {
e.printStackTrace();
}

View File

@ -53,21 +53,25 @@ class ManuallyRealNameFragment : NormalFragment() {
val selectedImage = data.data ?: return
val filePathColumn = arrayOf(MediaStore.Images.Media.DATA)
val cursor = requireContext().contentResolver.query(
selectedImage,
filePathColumn,
null,
null,
null
) ?: return
try {
val cursor = requireContext().contentResolver.query(
selectedImage,
filePathColumn,
null,
null,
null
) ?: return
cursor.moveToFirst()
cursor.moveToFirst()
val columnIndex = cursor.getColumnIndex(filePathColumn[0])
val picturePath = cursor.getString(columnIndex)
cursor.close()
val columnIndex = cursor.getColumnIndex(filePathColumn[0])
val picturePath = cursor.getString(columnIndex)
cursor.close()
uploadPicture(selectedImage, picturePath)
uploadPicture(selectedImage, picturePath)
} catch (e: Exception) {
ToastUtils.showToast(e.localizedMessage ?: "")
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

View File

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<shape xmlns:android="http://schemas.android.com/apk/res/android">
<solid android:color="@color/transparent" />
<corners android:radius="999dp" />
<stroke
android:color="#FF945420"
android:width="1dp" />
</shape>

View File

@ -0,0 +1,28 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<!-- 设置背景色 -->
<item android:id="@android:id/background">
<shape>
<corners android:radius="999dp" />
<gradient
android:endColor="#FFFFF3C0"
android:startColor="#FFFFF3C0" />
</shape>
</item>
<!-- 设置进度条颜色 -->
<item android:id="@android:id/progress">
<scale android:scaleWidth="100%">
<shape>
<corners android:radius="999dp" />
<gradient
android:endColor="#FFFCE072"
android:startColor="#FFFCE072" />
</shape>
</scale>
</item>
</layer-list>

View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:padding="4dp"
android:gravity="center_horizontal"
android:orientation="vertical">
<ImageView
android:id="@+id/browsePic"
android:layout_width="72dp"
android:layout_height="64dp"
android:src="@drawable/pic_browse_square" />
<View
android:layout_below="@+id/browsePic"
android:layout_width="64dp"
android:layout_height="8dp"
android:layout_marginTop="4dp"
android:layout_centerHorizontal="true"
android:background="@drawable/bg_browse_square_progress" />
<ProgressBar
android:id="@+id/browsePro"
android:layout_below="@+id/browsePic"
style="?android:attr/progressBarStyleHorizontal"
android:layout_width="62dp"
android:layout_height="6dp"
android:layout_marginTop="5dp"
android:layout_centerHorizontal="true"
android:progressDrawable="@drawable/progressbar_browse_square_style" />
</RelativeLayout>

View File

@ -10,6 +10,7 @@ import com.android.builder.model.AndroidArtifact
import com.android.utils.FileUtils
import com.gh.gamecenter.plugin.transform.DiskLruCacheTransformer
import com.gh.gamecenter.plugin.transform.ExoSourceManagerTransformer
import com.gh.gamecenter.plugin.transform.RoomTransformer
import javassist.ClassPool
import org.apache.commons.codec.digest.DigestUtils
import org.apache.commons.io.IOUtils
@ -32,6 +33,7 @@ class GhTransform(var project: Project) : Transform() {
init {
transformHelper.addTransformer(ExoSourceManagerTransformer())
transformHelper.addTransformer(DiskLruCacheTransformer())
transformHelper.addTransformer(RoomTransformer())
}
/**
@ -137,8 +139,7 @@ class GhTransform(var project: Project) : Transform() {
while (entries.hasMoreElements()) {
val jarInputEntry = entries.nextElement()
val jarInputEntryName = jarInputEntry.name
val outputJarEntry = JarEntry(jarInputEntryName)
val outputJarEntry = JarEntry(jarInputEntryName)
jarOutputStream.putNextEntry(outputJarEntry)
val inputStream = inputJarFile.getInputStream(jarInputEntry)
@ -159,7 +160,7 @@ class GhTransform(var project: Project) : Transform() {
private fun shouldModify(filePath: String): Boolean {
return filePath.endsWith(".class")
&& !filePath.contains("R.class")
&& !filePath.contains("$")
// && !filePath.contains("$")
&& !filePath.contains("R$")
&& !filePath.contains("BuildConfig.class")
}

View File

@ -10,7 +10,7 @@ import java.util.jar.JarOutputStream
class GhTransformHelper {
val transformers = ArrayList<Transformer>()
private val transformers = ArrayList<Transformer>()
fun addTransformer(transformer: Transformer) {
transformers.add(transformer)

View File

@ -12,7 +12,7 @@ class DiskLruCacheTransformer : Transformer {
private val classPool = ClassPool.getDefault()
override fun getModifyClassName(): String {
return "DiskLruCache"
return "DiskLruCache.class"
}
override fun modifyClass(filePath: String, inputStream: InputStream): CtClass? {

View File

@ -12,7 +12,7 @@ class ExoSourceManagerTransformer : Transformer {
private val classPool = ClassPool.getDefault()
override fun getModifyClassName() : String{
return "ExoSourceManager"
return "ExoSourceManager.class"
}
override fun modifyClass(filePath: String, inputStream: InputStream): CtClass? {

View File

@ -0,0 +1,45 @@
package com.gh.gamecenter.plugin.transform
import javassist.ClassPool
import javassist.CtClass
import javassist.CtNewMethod
import javassist.bytecode.ClassFile
import java.io.BufferedInputStream
import java.io.DataInputStream
import java.io.InputStream
class RoomTransformer : Transformer {
private val classPool = ClassPool.getDefault()
override fun getModifyClassName(): String {
return "InvalidationTracker\$1.class"
}
override fun modifyClass(filePath: String, inputStream: InputStream): CtClass? {
if (filePath.contains(getModifyClassName())) {
val classFile = ClassFile(DataInputStream(BufferedInputStream(inputStream)))
val ctClass = classPool.get(classFile.name)
if (ctClass.isFrozen) {
ctClass.defrost()
}
val ctMethod = ctClass.getDeclaredMethod("run")
val newMethodName = ctMethod.name + "Copy"
val newMethod = CtNewMethod.copy(ctMethod, newMethodName, ctClass, null)
ctClass.addMethod(newMethod)
val sb = StringBuffer()
sb.append("{try{")
sb.append(newMethodName)
sb.append("();}catch(Exception ex){ ex.printStackTrace(); }")
sb.append("}")
println("Insert Code:$sb")
ctMethod.setBody(sb.toString())
return ctClass
}
return null
}
}

View File

@ -7,8 +7,8 @@ ext {
targetSdkVersion = 26
// application info (每个大版本之间的 versionCode 增加 20)
versionCode = 452
versionName = "5.5.2"
versionCode = 458
versionName = "5.5.7"
applicationId = "com.gh.gamecenter"
// AndroidX
@ -97,7 +97,7 @@ ext {
flexbox = "1.1.0"
pickerView = "4.1.8"
verifier = "1.0.6"
skeleton = "1.1.4"
skeleton = "1.1.5"
mta = "6.7.9"
romChecker = "1.0.3"
oss = "2.9.2"
@ -109,11 +109,11 @@ ext {
apkParser = "v2.6.10"
nanohttpd = "2.3.1"
aliyunLog = "2.5.14"
easyFloat = "1.3.4"
easyFloat = "2.0.4"
shapeOfView = "1.4.7"
splitties = "3.0.0"
sentry = "4.3.0"
lancet_version = "v1.0.6"
}
}

View File

@ -53,6 +53,8 @@ QUICK_LOGIN_APPKEY=002BAABA2C078342DA33BEAB0A4C6A25
# hosts
DEV_API_HOST=https\://dev-and-api.ghzs.com/v5d5d0/
API_HOST=https\://and-api.ghzs.com/v5d5d0/
NEW_DEV_API_HOST=https\://dev-app-api.ghzs.com/
NEW_API_HOST=https\://app-api.ghzs.com/
android.useAndroidX=true
android.enableJetifier=true