Compare commits
34 Commits
feat/cloud
...
fix/galler
| Author | SHA1 | Date | |
|---|---|---|---|
| 8b077e4962 | |||
| ab795ab538 | |||
| ba0854ad9a | |||
| fc2051387a | |||
| ab2973c7be | |||
| 2a08ea681d | |||
| e23d510fb0 | |||
| 3c6ee0c782 | |||
| 07840822a8 | |||
| 12e547d333 | |||
| 8bb3736ad1 | |||
| aa9ba5163f | |||
| 23033edc42 | |||
| 308e134aff | |||
| ac78ea0498 | |||
| 38bab9cf4f | |||
| 8084cda37d | |||
| e624f34de1 | |||
| b832c0c14f | |||
| 6610c43937 | |||
| ec29d94fb7 | |||
| b6ec74d789 | |||
| 2d7224cf16 | |||
| 3f45344b54 | |||
| 1c3dbce08d | |||
| 7844800b0e | |||
| ebcfd9c85d | |||
| 3825315f65 | |||
| 3ffe4f9bc6 | |||
| b2fc01ae48 | |||
| 06f932af14 | |||
| c2fe3bb64a | |||
| b1b231a309 | |||
| e5161ae350 |
@ -1,5 +1,6 @@
|
||||
package com.gh.common.provider
|
||||
|
||||
import com.gh.common.util.PackageUtils
|
||||
import com.gh.gamecenter.core.provider.IAcceleratorDataHolderProvider
|
||||
import com.gh.gamecenter.feature.entity.VipEntity
|
||||
import com.halo.assistant.accelerator.repository.AcceleratorDataHolder
|
||||
@ -12,12 +13,8 @@ class IAcceleratorDataHolderProviderImpl : IAcceleratorDataHolderProvider {
|
||||
}
|
||||
}
|
||||
|
||||
override fun addInitFunResult(result: String) {
|
||||
AcceleratorDataHolder.instance.addInitFunResult(result)
|
||||
}
|
||||
|
||||
override fun getInitFunResults(): List<String> {
|
||||
return AcceleratorDataHolder.instance.initResults
|
||||
override fun getGhVersionName(): String {
|
||||
return PackageUtils.getGhVersionName()
|
||||
}
|
||||
|
||||
override fun clear() {
|
||||
|
||||
@ -306,21 +306,14 @@ object XapkInstaller : XApkUnZipCallback, XApkUnZipOutputFactory {
|
||||
DownloadNotificationHelper.addOrUpdateDownloadNotification(downloadEntity)
|
||||
NDataChanger.notifyDataChanged(downloadEntity)
|
||||
DownloadManager.getInstance().updateDownloadEntity(downloadEntity)
|
||||
// 仅官网渠道上报 XAPK 异常信息
|
||||
if (HaloApp.getInstance().channel == "GH_206") {
|
||||
SentryHelper.onEvent(
|
||||
"XAPK_UNZIP_ERROR",
|
||||
"gameName", downloadEntity.name,
|
||||
"errorDigest", exception.localizedMessage
|
||||
)
|
||||
}
|
||||
|
||||
DownloadDataHelper.uploadDownloadStatusEvent(downloadEntity, "xapk解压失败")
|
||||
|
||||
SensorsBridge.trackGameDecompressionFailed(
|
||||
downloadEntity.gameId,
|
||||
downloadEntity.name,
|
||||
downloadEntity.categoryChinese
|
||||
downloadEntity.categoryChinese,
|
||||
exception.localizedMessage ?: "unknown error"
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@ -114,7 +114,6 @@ class GameDetailActivity : DownloadToolbarActivity() {
|
||||
view,
|
||||
listOf(
|
||||
R.id.menu_download_iv,
|
||||
R.id.gameBigEvent,
|
||||
R.id.cardContainer,
|
||||
R.id.iv_reserve,
|
||||
R.id.iv_concern,
|
||||
|
||||
@ -127,6 +127,8 @@ class GameDetailViewModel(
|
||||
var isSkipOnPageSelected = false // 是否触发论坛/专区Tab跳转
|
||||
|
||||
var defaultCoverEntity: CoverEntity? = null
|
||||
var coverTabSequence = 1 // 用于埋点,详情视频/图集tab 当前选中tab的序号,从1开始
|
||||
var coverTabName = "" // 用于埋点,详情视频/图集tab 详情视频/图集tab 当前选中tab的tab名称
|
||||
|
||||
var isGameInstalled = false
|
||||
private var isGameUpdatable = false
|
||||
|
||||
@ -45,6 +45,7 @@ import com.gh.gamecenter.common.base.fragment.BaseLazyFragment
|
||||
import com.gh.gamecenter.common.constant.Constants
|
||||
import com.gh.gamecenter.common.constant.EntranceConsts
|
||||
import com.gh.gamecenter.common.entity.LinkEntity
|
||||
import com.gh.gamecenter.common.eventbus.EBReuse
|
||||
import com.gh.gamecenter.common.exposure.ExposureSource
|
||||
import com.gh.gamecenter.common.json.json
|
||||
import com.gh.gamecenter.common.mvvm.Status
|
||||
@ -1111,6 +1112,13 @@ class GameDetailWrapperFragment : BaseLazyFragment(), IScrollable {
|
||||
return true
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun onEventMainThread(reuse: EBReuse) {
|
||||
if ("download" == reuse.type) {
|
||||
downloadBinding.detailProgressbar.performClick()
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe(threadMode = ThreadMode.MAIN)
|
||||
fun onEventMainThread(status: EBDownloadStatus) {
|
||||
updateDownloadCountHint(packageViewModel.filterSameUpdateLiveData.value)
|
||||
|
||||
@ -21,13 +21,14 @@ class StartingAcceleratorViewModel : ViewModel() {
|
||||
|
||||
val useCase = AccelerationUseCase()
|
||||
|
||||
private val _restartingAcceleratorAction = MutableLiveData<Event<Boolean>>()
|
||||
val restartingAcceleratorAction: LiveData<Event<Boolean>> = _restartingAcceleratorAction
|
||||
private val _restartingAcceleratorAction = MutableLiveData<Event<Unit>>()
|
||||
val restartingAcceleratorAction: LiveData<Event<Unit>> = _restartingAcceleratorAction
|
||||
fun loadAcceleratorToken() {
|
||||
val userId = UserManager.getInstance().userId
|
||||
if (userId.isNotBlank()) {
|
||||
UserRepository.getInstance().setAcceleratorToken(userId) {
|
||||
_restartingAcceleratorAction.value = Event(it)
|
||||
// 这里就算setToken失败,也要调用启动加速,失败会走正常的日志上报
|
||||
_restartingAcceleratorAction.value = Event(Unit)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -187,15 +187,19 @@ class GameDetailFragment : LazyFragment(), IScrollable {
|
||||
coverSfv.goneIf(!shouldShowCoverFilter) {
|
||||
val defaultTabPosition =
|
||||
tabNameList.indexOfFirst { tabName -> viewModel.defaultCoverEntity?.tabName == tabName }
|
||||
viewModel.coverTabSequence = defaultTabPosition + 1
|
||||
viewModel.coverTabName = viewModel.defaultCoverEntity?.tabName ?: ""
|
||||
coverSfv.setItemList(tabNameList, if (defaultTabPosition != -1) defaultTabPosition else 0)
|
||||
coverSfv.setOnCheckedCallback { position ->
|
||||
val checkedText = tabNameList.getOrNull(position)
|
||||
val currentCoverEntity = it.getOrNull(coverPosition)
|
||||
viewModel.coverTabSequence = position + 1
|
||||
viewModel.coverTabName = checkedText ?: ""
|
||||
SensorsBridge.trackEvent("GameDetailMediaTabClick", json {
|
||||
"game_id" to gameEntity?.id
|
||||
"game_name" to gameEntity?.name
|
||||
"sequence" to position + 1
|
||||
"tab_name" to checkedText
|
||||
"sequence" to viewModel.coverTabSequence
|
||||
"tab_name" to viewModel.coverTabName
|
||||
})
|
||||
if (currentCoverEntity?.tabName == checkedText) return@setOnCheckedCallback
|
||||
|
||||
@ -307,7 +311,7 @@ class GameDetailFragment : LazyFragment(), IScrollable {
|
||||
|
||||
private fun initDetailRv() {
|
||||
binding.detailRv.run {
|
||||
(itemAnimator as DefaultItemAnimator).supportsChangeAnimations = false
|
||||
itemAnimator = null
|
||||
layoutManager = detailLayoutManager
|
||||
adapter = detailListAdapter
|
||||
addOnScrollListener(object : OnScrollListener() {
|
||||
|
||||
@ -115,7 +115,6 @@ class GameDetailCoverAdapter(
|
||||
})
|
||||
.build(holder.binding.player)
|
||||
|
||||
holder.binding.player.gameName = viewModel.game?.name ?: ""
|
||||
holder.binding.player.viewModel = viewModel
|
||||
holder.binding.player.showOrHideCoverFilter = showOrHideCoverFilter
|
||||
holder.binding.player.video = topVideo
|
||||
|
||||
@ -46,7 +46,7 @@ class GameDetailBriefItemViewHolder(
|
||||
highlightedTextClickListener = TextHelper.CopyToClipboardHighlightedTextClick()
|
||||
)
|
||||
briefTv.post {
|
||||
expandTv.isVisible = briefTv.lineCount == 3 && briefTv.layout.getEllipsisCount(2) > 0
|
||||
expandTv.isVisible = briefTv.lineCount == 3 && (briefTv.layout?.getEllipsisCount(2) ?: 0) > 0
|
||||
}
|
||||
expandTv.setOnClickListener {
|
||||
SensorsBridge.trackGameDetailModuleClick(
|
||||
|
||||
@ -194,6 +194,8 @@ class GameDetailComprehensivePanelItemViewHolder(
|
||||
maxLines = if (parentViewHolder.showPart && !parentViewHolder.isExpand) 1 else Int.MAX_VALUE
|
||||
text = data.text
|
||||
post {
|
||||
if (layout == null) return@post
|
||||
|
||||
val hasEllipsize = layout.getEllipsisCount(0) > 0
|
||||
if (parentViewHolder.showPart && hasEllipsize && !parentViewHolder.binding.expandTv.isVisible) {
|
||||
parentViewHolder.binding.expandTv.isVisible = true
|
||||
|
||||
@ -27,7 +27,7 @@ class GameDetailDeveloperWordItemViewHolder(
|
||||
.fromHtmlCompat(PicassoImageGetter(contentTv), ExtraTagHandler())
|
||||
)
|
||||
contentTv.post {
|
||||
expandTv.isVisible = (contentTv.lineCount == 3 && contentTv.layout.getEllipsisCount(2) > 0) || contentTv.lineCount > 3
|
||||
expandTv.isVisible = (contentTv.lineCount == 3 && (contentTv.layout?.getEllipsisCount(2) ?: 0) > 0) || contentTv.lineCount > 3
|
||||
}
|
||||
expandTv.background = R.drawable.bg_ui_surface_expand_gradient.toDrawable(context)
|
||||
expandTv.setTextColor(com.gh.gamecenter.common.R.color.text_theme.toColor(context))
|
||||
|
||||
@ -36,7 +36,7 @@ class GameDetailUpdateItemViewHolder(
|
||||
}
|
||||
contentTv.text = entity.updateDes
|
||||
contentTv.post {
|
||||
expandTv.isVisible = contentTv.lineCount == 3 && contentTv.layout.getEllipsisCount(2) > 0
|
||||
expandTv.isVisible = contentTv.lineCount == 3 && (contentTv.layout?.getEllipsisCount(2) ?: 0) > 0
|
||||
}
|
||||
expandTv.background = R.drawable.bg_ui_surface_expand_gradient.toDrawable(context)
|
||||
expandTv.setTextColor(com.gh.gamecenter.common.R.color.text_theme.toColor(context))
|
||||
|
||||
@ -63,7 +63,7 @@ class HistoryApkListAdapter(
|
||||
holder.binding.expandTv.setTextColor(com.gh.gamecenter.common.R.color.text_theme.toColor(mContext))
|
||||
holder.binding.updateDescTv.text = apkEntity.updateDesc
|
||||
holder.binding.updateDescTv.post {
|
||||
holder.binding.expandTv.isVisible = holder.binding.updateDescTv.lineCount == 3 && holder.binding.updateDescTv.layout.getEllipsisCount(2) > 0
|
||||
holder.binding.expandTv.isVisible = holder.binding.updateDescTv.lineCount == 3 && (holder.binding.updateDescTv.layout?.getEllipsisCount(2) ?: 0) > 0
|
||||
}
|
||||
holder.binding.versionTv.text = "版本${apkEntity.version}"
|
||||
holder.binding.releaseDateTv.text = TimeUtils.getFormatTime(apkEntity.updateTime)
|
||||
|
||||
@ -14,6 +14,7 @@ import androidx.fragment.app.Fragment
|
||||
import com.gh.common.util.LogUtils
|
||||
import com.gh.download.cache.ExoCacheManager
|
||||
import com.gh.gamecenter.R
|
||||
import com.gh.gamecenter.common.base.GlobalActivityManager
|
||||
import com.gh.gamecenter.common.observer.MuteCallback
|
||||
import com.gh.gamecenter.common.observer.VolumeObserver
|
||||
import com.gh.gamecenter.common.utils.*
|
||||
@ -40,7 +41,6 @@ class TopVideoView @JvmOverloads constructor(context: Context, attrs: AttributeS
|
||||
private var mMuteCallback: MuteCallback
|
||||
private var mVolumeObserver: VolumeObserver? = null
|
||||
|
||||
var gameName = ""
|
||||
var video: CoverTabEntity.Video? = null
|
||||
var viewModel: GameDetailViewModel? = null
|
||||
var uuid = UUID.randomUUID().toString()
|
||||
@ -87,11 +87,21 @@ class TopVideoView @JvmOverloads constructor(context: Context, attrs: AttributeS
|
||||
}
|
||||
|
||||
setBackFromFullScreenListener {
|
||||
// if (it.id == R.id.fullscreen) {
|
||||
// MtaHelper.onEvent("游戏详情_顶部视频", "${getMtaKeyPrefix()}-退出全屏", combinedTitleAndId)
|
||||
// } else if (it.id == R.id.back) {
|
||||
// MtaHelper.onEvent("游戏详情_顶部视频", "${getMtaKeyPrefix()}-点击返回", combinedTitleAndId)
|
||||
// }
|
||||
if (it.id == R.id.fullscreen || it.id == R.id.back) {
|
||||
SensorsBridge.trackGameDetailVideoClick(
|
||||
gameName = viewModel?.game?.name ?: "",
|
||||
gameId = viewModel?.game?.id ?: "",
|
||||
gameType = viewModel?.game?.categoryChinese ?: "",
|
||||
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
|
||||
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
|
||||
action = if (it.id == R.id.fullscreen) "退出全屏" else "点击返回",
|
||||
playType = if (mIsAutoPlay) "自动播放" else "主动播放",
|
||||
isFullScreen = mIfCurrentIsFullscreen,
|
||||
sequence = viewModel?.coverTabSequence ?: 1,
|
||||
tabName = viewModel?.coverTabName ?: "",
|
||||
playLength = (currentPositionWhenPlaying / 1000).toString()
|
||||
)
|
||||
}
|
||||
clearFullscreenLayout()
|
||||
}
|
||||
|
||||
@ -126,13 +136,22 @@ class TopVideoView @JvmOverloads constructor(context: Context, attrs: AttributeS
|
||||
fun startPlayLogic(isAutoPlay: Boolean) {
|
||||
mIsAutoPlay = isAutoPlay
|
||||
violenceUpdateMuteStatus()
|
||||
// if (isAutoPlay) {
|
||||
// MtaHelper.onEvent("游戏详情_顶部视频", "视频播放方式", "自动播放")
|
||||
// MtaHelper.onEvent("游戏详情_顶部视频", "顶部视频-自动播放", combinedTitleAndId)
|
||||
// } else {
|
||||
// MtaHelper.onEvent("游戏详情_顶部视频", "视频播放方式", "手动播放")
|
||||
// }
|
||||
|
||||
if (isAutoPlay) {
|
||||
SensorsBridge.trackGameDetailVideoClick(
|
||||
gameName = viewModel?.game?.name ?: "",
|
||||
gameId = viewModel?.game?.id ?: "",
|
||||
gameType = viewModel?.game?.categoryChinese ?: "",
|
||||
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
|
||||
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
|
||||
action = "自动播放",
|
||||
playType = if (mIsAutoPlay) "自动播放" else "主动播放",
|
||||
isFullScreen = mIfCurrentIsFullscreen,
|
||||
sequence = viewModel?.coverTabSequence ?: 1,
|
||||
tabName = viewModel?.coverTabName ?: "",
|
||||
playLength = (currentPositionWhenPlaying / 1000).toString()
|
||||
)
|
||||
|
||||
val seekTime = ScrollCalculatorHelper.getPlaySchedule(MD5Utils.getContentMD5(video?.url))
|
||||
seekOnStart = seekTime
|
||||
mTouchingProgressBar = false
|
||||
@ -289,7 +308,7 @@ class TopVideoView @JvmOverloads constructor(context: Context, attrs: AttributeS
|
||||
|
||||
override fun onStopTrackingTouch(seekBar: SeekBar?) {
|
||||
super.onStopTrackingTouch(seekBar)
|
||||
uploadVideoStreamingPlaying("拖动")
|
||||
uploadVideoStreamingPlaying("拖动进度条", seekBar)
|
||||
}
|
||||
|
||||
override fun isShowNetConfirm(): Boolean {
|
||||
@ -533,7 +552,7 @@ class TopVideoView @JvmOverloads constructor(context: Context, attrs: AttributeS
|
||||
}
|
||||
|
||||
override fun releaseVideos() {
|
||||
uploadVideoStreamingPlaying("结束播放")
|
||||
uploadVideoStreamingPlaying("播放完毕")
|
||||
CustomManager.releaseAllVideos(getKey())
|
||||
}
|
||||
|
||||
@ -556,11 +575,21 @@ class TopVideoView @JvmOverloads constructor(context: Context, attrs: AttributeS
|
||||
override fun onClick(v: View) {
|
||||
when (v.id) {
|
||||
R.id.start -> {
|
||||
// if (currentState == GSYVideoView.CURRENT_STATE_PLAYING) {
|
||||
// MtaHelper.onEvent("游戏详情_顶部视频", "${getMtaKeyPrefix()}-点击暂停", combinedTitleAndId)
|
||||
// } else {
|
||||
// MtaHelper.onEvent("游戏详情_顶部视频", "${getMtaKeyPrefix()}-点击播放", combinedTitleAndId)
|
||||
// }
|
||||
SensorsBridge.trackGameDetailVideoClick(
|
||||
gameName = viewModel?.game?.name ?: "",
|
||||
gameId = viewModel?.game?.id ?: "",
|
||||
gameType = viewModel?.game?.categoryChinese ?: "",
|
||||
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
|
||||
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
|
||||
action = if (currentState == GSYVideoView.CURRENT_STATE_PLAYING) "点击暂停" else "点击播放",
|
||||
playType = if (mIsAutoPlay) "自动播放" else "主动播放",
|
||||
isFullScreen = mIfCurrentIsFullscreen,
|
||||
sequence = viewModel?.coverTabSequence ?: 1,
|
||||
tabName = viewModel?.coverTabName ?: "",
|
||||
playLength = (currentPositionWhenPlaying / 1000).toString()
|
||||
)
|
||||
// 手动触发暂停/播放,后续行为都算主动播放
|
||||
mIsAutoPlay = false
|
||||
super.onClick(v)
|
||||
}
|
||||
|
||||
@ -568,13 +597,11 @@ class TopVideoView @JvmOverloads constructor(context: Context, attrs: AttributeS
|
||||
}
|
||||
}
|
||||
|
||||
private fun getMtaKeyPrefix() = if (mIfCurrentIsFullscreen) "顶部视频(全屏)" else "顶部视频"
|
||||
|
||||
fun getCurrentPosition(): Long {
|
||||
return mCurrentPosition
|
||||
}
|
||||
|
||||
fun uploadVideoStreamingPlaying(action: String) {
|
||||
fun uploadVideoStreamingPlaying(action: String, seekBar: SeekBar? = null) {
|
||||
if (video == null || video?.url.isNullOrEmpty()) return
|
||||
runOnIoThread(isHeavyWightTask = true) {
|
||||
val isLandscape = mOrientationUtils != null
|
||||
@ -598,6 +625,26 @@ class TopVideoView @JvmOverloads constructor(context: Context, attrs: AttributeS
|
||||
action, video?.videoId, video?.title, viewModel?.game?.id, viewModel?.game?.name,
|
||||
videoPlayModel, videoPlayStatus(), mContentLength, videoTotalTime, videoPlayTs, progress.toInt()
|
||||
)
|
||||
if (action != "开始播放" && action != "暂停播放" && action != "退出全屏") {
|
||||
val playLength = when (action) {
|
||||
"播放完毕" -> (duration / 1000).toString()
|
||||
"拖动进度条" -> ((seekBar?.progress ?: 0) * duration / 100000).toString()
|
||||
else -> (currentPositionWhenPlaying / 1000).toString()
|
||||
}
|
||||
SensorsBridge.trackGameDetailVideoClick(
|
||||
gameName = viewModel?.game?.name ?: "",
|
||||
gameId = viewModel?.game?.id ?: "",
|
||||
gameType = viewModel?.game?.categoryChinese ?: "",
|
||||
lastPageName = GlobalActivityManager.getLastPageEntity().pageName,
|
||||
lastPageId = GlobalActivityManager.getLastPageEntity().pageId,
|
||||
action = action,
|
||||
playType = if (mIsAutoPlay) "自动播放" else "主动播放",
|
||||
isFullScreen = mIfCurrentIsFullscreen,
|
||||
sequence = viewModel?.coverTabSequence ?: 1,
|
||||
tabName = viewModel?.coverTabName ?: "",
|
||||
playLength = playLength
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -72,7 +72,7 @@ object CustomViewExt {
|
||||
private fun getTestDescription(game: GameEntity): String {
|
||||
val timeText = TimeUtils.formatTestTime(game.test?.start ?: 0L)
|
||||
val eventName = if (game.test?.type == "删档内测") {
|
||||
R.string.first_release.toResString()
|
||||
R.string.delete_test.toResString()
|
||||
} else {
|
||||
R.string.go_live.toResString()
|
||||
}
|
||||
|
||||
@ -110,8 +110,11 @@ class CustomGameGallerySlideViewHolder(
|
||||
|
||||
private val dataList = arrayListOf<GameEntity>()
|
||||
fun submitList(data: List<GameEntity>) {
|
||||
val newSubData = data.filterIndexed { i, _ -> i % 3 == index }
|
||||
|
||||
dataList.clear()
|
||||
dataList.addAll(data)
|
||||
dataList.addAll(newSubData)
|
||||
|
||||
notifyDataSetChanged()
|
||||
}
|
||||
|
||||
@ -124,8 +127,7 @@ class CustomGameGallerySlideViewHolder(
|
||||
override fun onBindViewHolder(holder: GameGallerySlideItemViewHolder, position: Int) {
|
||||
if (dataList.isEmpty()) return
|
||||
|
||||
val dataPosition = position * 3 + index
|
||||
val realPosition = dataPosition % dataList.size
|
||||
val realPosition = position % dataList.size
|
||||
val gameEntity = dataList[realPosition]
|
||||
|
||||
exposureInvoke(realPosition, gameEntity)
|
||||
|
||||
@ -37,6 +37,8 @@ class NotificationColumnViewHolder(
|
||||
|
||||
private var isScrolling = false
|
||||
|
||||
private var targetPosition = -1
|
||||
|
||||
private val bannerController = BannerInRecyclerController {
|
||||
nextToPage()
|
||||
}
|
||||
@ -190,6 +192,10 @@ class NotificationColumnViewHolder(
|
||||
override fun onViewAttach(parent: RecyclerView?) {
|
||||
viewModel.shareHiddenNotifications.observe(lifecycleOwner, hiddenNotifiesObserver)
|
||||
bannerController.onViewAttachedToWindow(parent)
|
||||
val selectedPosition = (_item as? CustomCommonContentCollectionItem)?.selectedPosition ?: 0
|
||||
if (targetPosition != -1 && targetPosition != selectedPosition) {
|
||||
binding.rvNotification.scrollToPosition(targetPosition)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onViewDetach(parent: RecyclerView?) {
|
||||
@ -203,7 +209,10 @@ class NotificationColumnViewHolder(
|
||||
if (layoutManager is LinearLayoutManager) {
|
||||
val firstPosition = layoutManager.findFirstCompletelyVisibleItemPosition()
|
||||
if (firstPosition != -1) {
|
||||
binding.rvNotification.smoothScrollToPosition(firstPosition + 1)
|
||||
// 请注意,有可能smoothScrollToPosition正在执行滚动动画时,当前ViewHolder会调用onViewDetach,导致RecyclerView无法滚动到目标位置,所以这里需要先记录目标位置
|
||||
// 当ViewHolder Detach之后,再次Attach时,检查targetPosition是否等于selectedPosition,如果不相等,说明发生了以上情况,需要再次调用scrollToPosition将RecyclerView滚动到指定位置
|
||||
targetPosition = firstPosition + 1
|
||||
binding.rvNotification.smoothScrollToPosition(targetPosition)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -52,7 +52,7 @@ class UploadThread(
|
||||
.setCancelHook(true)
|
||||
.setCheckpointFile(recordDirectory)
|
||||
.setPartSize(10 * 1024 * 1024)
|
||||
.setTaskNum(2)
|
||||
.setTaskNum(1)
|
||||
.setDataTransferListener {
|
||||
Utils.log(
|
||||
"OssUpload",
|
||||
@ -74,9 +74,9 @@ class UploadThread(
|
||||
mUploadInput = this
|
||||
}
|
||||
val config = TransportConfig.builder()
|
||||
.readTimeoutMills(15 * 1000)
|
||||
.writeTimeoutMills(15 * 1000)
|
||||
.connectTimeoutMills(15 * 1000)
|
||||
.readTimeoutMills(5 * 1000)
|
||||
.writeTimeoutMills(5 * 1000)
|
||||
.connectTimeoutMills(5 * 1000)
|
||||
.maxRetryCount(2)
|
||||
.build()
|
||||
|
||||
|
||||
@ -26,6 +26,7 @@ import org.json.JSONException
|
||||
import org.json.JSONObject
|
||||
import java.io.File
|
||||
import java.io.IOException
|
||||
import java.net.MalformedURLException
|
||||
import java.net.URL
|
||||
import java.net.URLConnection
|
||||
import java.text.DecimalFormat
|
||||
@ -341,6 +342,9 @@ object NDownloadBridge : InnerDownloadListener, IErrorRetryHandler {
|
||||
// 由于这里的异常不会影响正常下载,所以直接打印异常,不做处理
|
||||
// 具体可见 https://sentry.shanqu.cc/organizations/lightgame/issues/371082/
|
||||
e.printStackTrace()
|
||||
} catch (e: MalformedURLException) {
|
||||
// 由于重定向的 url 可能是一个不合法的 url,这里捕获异常
|
||||
e.printStackTrace()
|
||||
}
|
||||
|
||||
NDataChanger.notifyDataChanged(downloadEntity)
|
||||
|
||||
@ -20,14 +20,6 @@ class AcceleratorDataHolder {
|
||||
|
||||
private val listeners = mutableSetOf<OnDataHolderListener>()
|
||||
|
||||
private val _initResults = arrayListOf<String>()
|
||||
val initResults: List<String>
|
||||
get() = _initResults
|
||||
|
||||
fun addInitFunResult(result: String) {
|
||||
_initResults.add(result)
|
||||
}
|
||||
|
||||
private var _hasAcctGameInfoInLocal = false
|
||||
val hasAcctGameInfoInLocal: Boolean
|
||||
get() = _hasAcctGameInfoInLocal
|
||||
|
||||
@ -106,7 +106,8 @@ class RealNameInfoFragment : ToolbarFragment() {
|
||||
}
|
||||
|
||||
private fun initEditingView() {
|
||||
val bodyString = getText(R.string.realname_body_tv)
|
||||
val bodyString =
|
||||
"为响应《国家新闻出版署关于防止未成年沉迷网络游戏的通知》,请认真填写您的身份信息。您提供的证件信息将受到严格保护,仅用于用户实名制认证,不会用作其他用途,请放心填写。前往了解更多信息>>"
|
||||
mBinding.bodyTv.text =
|
||||
SpanBuilder(bodyString)
|
||||
.click(
|
||||
@ -124,13 +125,13 @@ class RealNameInfoFragment : ToolbarFragment() {
|
||||
.build()
|
||||
mBinding.bodyTv.movementMethod = CustomLinkMovementMethod.getInstance()
|
||||
|
||||
val hintString = getText(R.string.realname_hint_tv)
|
||||
val hintString = "特别说明:由于部分用户之前的实名信息不正确或认证失败,可能需要重新认证,请提交真实的信息进行认证即可。部分游戏仅对成年用户进行开放"
|
||||
mBinding.hintTv.text =
|
||||
SpanBuilder(hintString)
|
||||
.bold(0, 5)
|
||||
.build()
|
||||
|
||||
val manualHintString = getText(R.string.realname_manual_hint_tv)
|
||||
val manualHintString = "若您提交的真实身份信息未通过认证或者您持有的为港澳台\\国外身份证件,可转交人工审核"
|
||||
mBinding.manualHintTv.text =
|
||||
SpanBuilder(manualHintString)
|
||||
.click(
|
||||
@ -160,9 +161,6 @@ class RealNameInfoFragment : ToolbarFragment() {
|
||||
mBinding.nameEt.doOnTextChanged { _, _, _, _ ->
|
||||
updateSubmitBtn()
|
||||
}
|
||||
mBinding.textDotIndicator.setOnClickListener {
|
||||
mBinding.nameEt.text.insert(mBinding.nameEt.selectionStart, "\u00B7")
|
||||
}
|
||||
mBinding.idCardEt.doOnTextChanged { _, _, _, _ ->
|
||||
updateSubmitBtn()
|
||||
}
|
||||
|
||||
@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<shape xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:shape="rectangle">
|
||||
<corners android:radius="2dp" />
|
||||
<stroke android:color="@color/ui_skeleton_frame" android:width="1dp" />
|
||||
</shape>
|
||||
@ -34,7 +34,7 @@
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:text="@string/realname_body_tv" />
|
||||
tools:text="为响应《国家新闻出版署关于防止未成年沉迷网络游戏的通知》,请认真填写您的身份信息。您提供的证件信息将受到严格保护,仅用于用户实名制认证,不会用作其他用途,请放心填写。前往了解更多信息>>" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/hintTv"
|
||||
@ -48,7 +48,7 @@
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/bodyTv"
|
||||
tools:text="@string/realname_hint_tv" />
|
||||
tools:text="特别说明:由于部分用户之前的实名信息不正确或认证失败,可能需要重新认证,请提交真实的信息进行认证即可。部分游戏仅对成年用户进行开放" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/badgeContainer"
|
||||
@ -109,10 +109,9 @@
|
||||
|
||||
<EditText
|
||||
android:id="@+id/nameEt"
|
||||
android:layout_width="0dp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="40dp"
|
||||
android:layout_marginTop="12dp"
|
||||
android:layout_marginEnd="8dp"
|
||||
android:background="@drawable/bg_shape_fa_radius_2"
|
||||
android:hint="请输入真实姓名"
|
||||
android:padding="8dp"
|
||||
@ -121,22 +120,8 @@
|
||||
android:textColorHint="@color/text_instance"
|
||||
android:textCursorDrawable="@drawable/cursor_color"
|
||||
android:textSize="14sp"
|
||||
app:layout_constraintEnd_toStartOf="@+id/textDotIndicator"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/nameTv" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/textDotIndicator"
|
||||
android:layout_width="40dp"
|
||||
android:layout_height="40dp"
|
||||
android:background="@drawable/bg_stroke_fa_radius_2"
|
||||
android:gravity="center"
|
||||
android:text="@string/realname_dot_indicator"
|
||||
android:textSize="14sp"
|
||||
android:textColor="@color/text_secondary"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintTop_toTopOf="@+id/nameEt" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/idCardTv"
|
||||
android:layout_width="wrap_content"
|
||||
@ -192,7 +177,7 @@
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toBottomOf="@id/submitBtn"
|
||||
tools:text="@string/realname_manual_hint_tv" />
|
||||
tools:text="若您提交的真实身份信息未通过认证或者您持有的为港澳台\国外身份证件,可转交人工审核" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/errorHintTv"
|
||||
|
||||
@ -1,310 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<androidx.coordinatorlayout.widget.CoordinatorLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
xmlns:tools="http://schemas.android.com/tools"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
android:orientation="vertical">
|
||||
|
||||
<com.google.android.material.appbar.AppBarLayout
|
||||
android:id="@+id/gamedetail_appbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:background="@color/ui_surface"
|
||||
android:fitsSystemWindows="true"
|
||||
android:gravity="center"
|
||||
app:layout_behavior="com.gh.gamecenter.common.view.FixAppBarLayoutBehavior"
|
||||
tools:visibility="visible">
|
||||
|
||||
<com.google.android.material.appbar.CollapsingToolbarLayout
|
||||
android:id="@+id/collapsingToolbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:fitsSystemWindows="true"
|
||||
app:contentScrim="@color/ui_surface"
|
||||
app:layout_scrollFlags="scroll|exitUntilCollapsed"
|
||||
app:scrimAnimationDuration="0"
|
||||
app:scrimVisibleHeightTrigger="105dp"
|
||||
app:titleEnabled="false">
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:fitsSystemWindows="true"
|
||||
android:gravity="center_horizontal"
|
||||
android:orientation="vertical">
|
||||
|
||||
<include
|
||||
android:id="@+id/game_detail_video"
|
||||
layout="@layout/piece_game_detail_video" />
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:paddingLeft="12dp"
|
||||
android:paddingTop="16dp"
|
||||
android:paddingRight="16dp"
|
||||
android:paddingBottom="12dp">
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/gameIconContainer"
|
||||
android:layout_width="96dp"
|
||||
android:layout_height="88dp"
|
||||
android:layout_marginRight="12dp"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintTop_toTopOf="parent">
|
||||
|
||||
<com.gh.gamecenter.feature.view.GameIconView
|
||||
android:id="@+id/gamedetail_iv_thumb"
|
||||
android:layout_width="88dp"
|
||||
android:layout_height="88dp"
|
||||
android:layout_centerHorizontal="true"
|
||||
app:gameIconFadeDuration="0" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/gameDetailRankLl"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="25dp"
|
||||
android:layout_alignParentBottom="true"
|
||||
android:background="@drawable/bg_game_detail_rank"
|
||||
android:orientation="horizontal"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="6dp"
|
||||
android:layout_marginTop="7dp"
|
||||
android:src="@drawable/ic_game_detail_rank_trophy" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/gameDetailRankTv"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerHorizontal="true"
|
||||
android:layout_marginLeft="2dp"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginRight="2dp"
|
||||
android:layout_weight="1"
|
||||
android:ellipsize="marquee"
|
||||
android:gravity="center"
|
||||
android:includeFontPadding="false"
|
||||
android:marqueeRepeatLimit="marquee_forever"
|
||||
android:singleLine="true"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="9sp"
|
||||
android:textStyle="bold"
|
||||
tools:text="预约榜第1名" />
|
||||
|
||||
<ImageView
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginTop="8dp"
|
||||
android:layout_marginRight="6dp"
|
||||
android:src="@drawable/ic_game_detail_rank_arrow" />
|
||||
</LinearLayout>
|
||||
</RelativeLayout>
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/gameTitleContainer"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="70dp"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="vertical"
|
||||
app:layout_constraintEnd_toStartOf="@+id/rating_score_container"
|
||||
app:layout_constraintStart_toEndOf="@+id/gameIconContainer"
|
||||
app:layout_constraintTop_toTopOf="@+id/gameIconContainer">
|
||||
|
||||
<TextView
|
||||
android:id="@+id/gamedetail_tv_name"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:ellipsize="end"
|
||||
android:includeFontPadding="false"
|
||||
android:lineSpacingExtra="2dp"
|
||||
android:maxLines="2"
|
||||
android:textColor="@color/text_primary"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold"
|
||||
tools:text="地海争霸2" />
|
||||
|
||||
<com.gh.common.view.FlexLinearLayout
|
||||
android:id="@+id/gamedetail_gametag"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="20dp"
|
||||
android:layout_marginTop="4dp"
|
||||
android:clipToPadding="false"
|
||||
android:orientation="horizontal" />
|
||||
</LinearLayout>
|
||||
|
||||
<ImageView
|
||||
android:id="@+id/recommendAgeIv"
|
||||
android:layout_width="58dp"
|
||||
android:layout_height="14dp"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="@+id/gameIconContainer"
|
||||
app:layout_constraintStart_toEndOf="@+id/gameIconContainer"
|
||||
tools:src="@drawable/ic_recommend_age8"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/realnameHintTv"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="14dp"
|
||||
android:layout_marginStart="8dp"
|
||||
android:background="@drawable/bg_ebf8ff_radius_2"
|
||||
android:gravity="center"
|
||||
android:paddingEnd="6dp"
|
||||
android:paddingStart="6dp"
|
||||
android:paddingTop="0.5dp"
|
||||
android:text="登陆游戏后需进行实名认证"
|
||||
android:textColor="@color/text_theme"
|
||||
android:textSize="@dimen/tag_text_size"
|
||||
android:includeFontPadding="false"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintBottom_toBottomOf="@id/gameIconContainer"
|
||||
app:layout_constraintStart_toEndOf="@id/recommendAgeIv"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/rating_score_container"
|
||||
android:layout_width="64dp"
|
||||
android:layout_height="64dp"
|
||||
android:layout_marginLeft="6dp"
|
||||
android:visibility="gone"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintStart_toEndOf="@+id/gameTitleContainer"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
tools:visibility="visible">
|
||||
|
||||
<ImageView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:src="@drawable/bg_game_detail_rating_score" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/rating_score_average"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_centerInParent="true"
|
||||
android:gravity="center"
|
||||
android:textColor="@color/white"
|
||||
android:textSize="18sp"
|
||||
android:textStyle="bold"
|
||||
tools:text="8.5" />
|
||||
|
||||
</RelativeLayout>
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/gameBigEvent"
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_gravity="left"
|
||||
android:layout_marginLeft="16dp"
|
||||
android:layout_marginRight="16dp"
|
||||
android:layout_marginBottom="16dp"
|
||||
android:background="@drawable/bg_game_big_event"
|
||||
android:drawableLeft="@drawable/ic_game_detail_big_event_gray"
|
||||
android:drawableRight="@drawable/ic_game_detail_big_event_arrow_gray"
|
||||
android:drawablePadding="3dp"
|
||||
android:ellipsize="end"
|
||||
android:includeFontPadding="false"
|
||||
android:maxLines="1"
|
||||
android:padding="4dp"
|
||||
android:textColor="@color/text_tertiary"
|
||||
android:textSize="10sp"
|
||||
android:visibility="gone"
|
||||
tools:text="游戏大事件游戏大事件"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/contentCardContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:paddingStart="16dp"
|
||||
android:paddingEnd="16dp"
|
||||
android:paddingBottom="8dp"
|
||||
android:visibility="gone" />
|
||||
|
||||
<View
|
||||
android:id="@+id/toolbarGapView"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="8dp"
|
||||
android:background="@color/ui_background" />
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.appcompat.widget.Toolbar
|
||||
android:id="@+id/toolbar"
|
||||
style="@style/Base_ToolbarStyle"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="44dp"
|
||||
android:background="@android:color/transparent"
|
||||
app:contentInsetStartWithNavigation="0dp"
|
||||
app:layout_collapseMode="pin">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/toolbarContainer"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:background="@color/transparent"
|
||||
android:gravity="center_vertical"
|
||||
android:orientation="horizontal"
|
||||
android:translationX="-10dp">
|
||||
|
||||
<com.gh.gamecenter.feature.view.GameIconView
|
||||
android:id="@+id/gamedetail_thumb_small"
|
||||
android:layout_width="28dp"
|
||||
android:layout_height="28dp"
|
||||
android:visibility="gone"
|
||||
tools:visibility="visible" />
|
||||
|
||||
<TextView
|
||||
android:id="@+id/titleTv"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginLeft="8dp"
|
||||
android:ellipsize="end"
|
||||
android:maxLines="1"
|
||||
android:textSize="16sp"
|
||||
android:textStyle="bold" />
|
||||
</LinearLayout>
|
||||
</androidx.appcompat.widget.Toolbar>
|
||||
|
||||
</com.google.android.material.appbar.CollapsingToolbarLayout>
|
||||
|
||||
<RelativeLayout
|
||||
android:id="@+id/gamedetail_tabbar"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<com.gh.gamecenter.common.view.TabIndicatorView
|
||||
android:id="@+id/tab_indicator"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/default_tab_indicator_height"
|
||||
android:layout_alignParentBottom="true" />
|
||||
|
||||
<com.google.android.material.tabs.TabLayout
|
||||
android:id="@+id/tab_layout"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/tab_layout_height"
|
||||
app:tabIndicator="@null"
|
||||
app:tabTextAppearance="@style/TabLayoutTextAppearance" />
|
||||
|
||||
</RelativeLayout>
|
||||
</com.google.android.material.appbar.AppBarLayout>
|
||||
|
||||
<com.lightgame.view.NoScrollableViewPager
|
||||
android:id="@+id/gamedetail_vp"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:overScrollMode="never"
|
||||
app:layout_behavior="@string/appbar_scrolling_view_behavior" />
|
||||
|
||||
</androidx.coordinatorlayout.widget.CoordinatorLayout>
|
||||
@ -1,39 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical">
|
||||
|
||||
<LinearLayout
|
||||
android:id="@+id/video_placeholder"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="vertical"
|
||||
android:visibility="gone">
|
||||
|
||||
<com.gh.gamecenter.common.view.StatusBarView
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content" />
|
||||
|
||||
<View
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="@dimen/appbar_height" />
|
||||
|
||||
</LinearLayout>
|
||||
|
||||
<androidx.constraintlayout.widget.ConstraintLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content">
|
||||
|
||||
<com.gh.gamecenter.gamedetail.video.TopVideoView
|
||||
android:id="@+id/player"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="0dp"
|
||||
app:layout_constraintDimensionRatio="h,180:101"
|
||||
app:layout_constraintTop_toTopOf="parent"
|
||||
app:layout_constraintStart_toStartOf="parent"
|
||||
app:layout_constraintEnd_toEndOf="parent"
|
||||
app:layout_constraintBottom_toBottomOf="parent" />
|
||||
</androidx.constraintlayout.widget.ConstraintLayout>
|
||||
</LinearLayout>
|
||||
@ -412,9 +412,6 @@
|
||||
<string name="realname_success_badge_hint_extra_underage">當前認証狀態:未成年</string>
|
||||
<string name="realname_pending_badge_hint">實名信息認証中...</string>
|
||||
<string name="realname_pending_badge_hint_extra">認証期間不影響您正常的遊戲體驗</string>
|
||||
<string name="realname_body_tv">爲響應《國家新聞出版署關於防止未成年沉迷網絡遊戲的通知》,請認真填冩您的身份信息。您提供的証件信息將受到嚴格保護,僅用於用戶實名製認証,不會用作其他用途,請放心填冩。前往了解更多信息>></string>
|
||||
<string name="realname_hint_tv">特別説明:由於部分用戶之前的實名信息不正確或認証失敗,可能需要重新認証,請提交真實的信息進行認証即可。部分遊戲僅對成年用戶進行開放。(特殊字符“·”可通過快捷鍵進行添加)</string>
|
||||
<string name="realname_manual_hint_tv">若您提交的真實身份信息未通過認証或者您持有的爲港澳颱\國外身份証件,可轉交人工審核</string>
|
||||
|
||||
<string name="interested_game_footer_hint">去 <Data><![CDATA[<font color="#1383EB">設置偏好</font>]]></Data> ,讓推薦更懂你的心~</string>
|
||||
|
||||
@ -686,9 +683,9 @@
|
||||
<string name="select_the_region">選擇加速區服</string>
|
||||
<string name="tips_for_new_users">新用戶免費3小時</string>
|
||||
<string name="recent_played">最近在玩</string>
|
||||
<string name="first_release">先發</string>
|
||||
<string name="go_live">上線</string>
|
||||
<string name="number_of_reservations">%1$s人預約</string>
|
||||
<string name="wechat_app_not_install_tips">請檢查是否安裝微信客戶端</string>
|
||||
<string name="delete_test">刪測</string>
|
||||
</resources>
|
||||
|
||||
|
||||
@ -412,10 +412,7 @@
|
||||
<string name="realname_success_badge_hint_extra_underage">当前认证状态:未成年</string>
|
||||
<string name="realname_pending_badge_hint">实名信息认证中...</string>
|
||||
<string name="realname_pending_badge_hint_extra">部分游戏在认证期间无法进行下载</string>
|
||||
<string name="realname_body_tv">为响应《国家新闻出版署关于防止未成年沉迷网络游戏的通知》,请认真填写您的身份信息。您提供的证件信息将受到严格保护,仅用于用户实名制认证,不会用作其他用途,请放心填写。前往了解更多信息>></string>
|
||||
<string name="realname_hint_tv">特别说明:由于部分用户之前的实名信息不正确或认证失败,可能需要重新认证,请提交真实的信息进行认证即可。部分游戏仅对成年用户进行开放。(特殊字符“·”可通过快捷键进行添加)</string>
|
||||
<string name="realname_manual_hint_tv">若您提交的真实身份信息未通过认证或者您持有的为港澳台\国外身份证件,可转交人工审核</string>
|
||||
<string name="realname_dot_indicator" translatable="false">•</string>
|
||||
|
||||
<string name="interested_game_footer_hint">去 <Data><![CDATA[<font color="#1383EB">设置偏好</font>]]></Data> ,让推荐更懂你的心~</string>
|
||||
|
||||
<item name="download_item_type" type="id" />
|
||||
@ -686,8 +683,8 @@
|
||||
<string name="select_the_region">选择加速区服</string>
|
||||
<string name="tips_for_new_users">新用户免费3小时</string>
|
||||
<string name="recent_played">最近在玩</string>
|
||||
<string name="first_release">首发</string>
|
||||
<string name="go_live">上线</string>
|
||||
<string name="number_of_reservations">%1$s人预约</string>
|
||||
<string name="wechat_app_not_install_tips">请检查是否安装微信客户端</string>
|
||||
<string name="delete_test">删测</string>
|
||||
</resources>
|
||||
|
||||
@ -7,8 +7,8 @@ ext {
|
||||
targetSdkVersion = 30 // 升级targetSdkVersion到 34 时需要根据官方文档补全前台服务的权限类型。比如 NDownloadService,KeepAliveService
|
||||
|
||||
// application info (每个大版本之间的 versionCode 增加 20)
|
||||
versionCode = 1150
|
||||
versionName = "5.40.0"
|
||||
versionCode = 1152
|
||||
versionName = "5.40.2"
|
||||
applicationId = "com.gh.gamecenter"
|
||||
applicationIdGat = "com.gh.gamecenter.intl"
|
||||
|
||||
@ -100,7 +100,7 @@ ext {
|
||||
skeleton = "1.1.5"
|
||||
mta = "6.8.0"
|
||||
romChecker = "1.0.3"
|
||||
oss = "2.6.0"
|
||||
oss = "2.8.8"
|
||||
desugarJdkLibs = "1.1.5"
|
||||
toolargetool = "0.3.0"
|
||||
chart = "3.1.0"
|
||||
@ -150,7 +150,7 @@ ext {
|
||||
|
||||
xcrashVersion = "3.1.0"
|
||||
aliPayVersion = "15.8.17"
|
||||
acceleratorVersion = "1.0.1"
|
||||
acceleratorVersion = "2.0.2"
|
||||
}
|
||||
|
||||
apply from: 'dependencies_vasdk.gradle'
|
||||
|
||||
@ -1,11 +1,14 @@
|
||||
package com.gh.gamecenter.accelerator.provider
|
||||
|
||||
import android.app.Application
|
||||
import com.gh.gamecenter.common.utils.EnvHelper
|
||||
import com.gh.gamecenter.core.HaloApp
|
||||
import com.gh.gamecenter.core.callback.AccelerateState
|
||||
import com.gh.gamecenter.core.callback.OnAccelerateListener
|
||||
import com.gh.gamecenter.core.provider.IAcceleratorDataHolderProvider
|
||||
import com.gh.gamecenter.core.provider.IAcceleratorProvider
|
||||
import com.gh.gamecenter.feature.entity.AcctGameInfo
|
||||
import com.gh.gamecenter.feature.utils.NewFlatLogUtils
|
||||
import com.gh.gamecenter.feature.utils.SentryHelper
|
||||
import com.lightgame.utils.Utils
|
||||
import com.qeeyou.qyvpn.QyAccelerator
|
||||
@ -23,6 +26,8 @@ import java.io.File
|
||||
class AcceleratorProviderImpl : IAcceleratorProvider {
|
||||
private var _token = ""
|
||||
|
||||
private val initResults = arrayListOf<String>()
|
||||
|
||||
// 根据包名回调
|
||||
private val listeners = hashMapOf<String, OnAccelerateListener>()
|
||||
|
||||
@ -91,8 +96,7 @@ class AcceleratorProviderImpl : IAcceleratorProvider {
|
||||
override fun onExecLifecycleInitFun(isEnter: Boolean) {
|
||||
super.onExecLifecycleInitFun(isEnter)
|
||||
Utils.log(LOG_TAG, "onExecLifecycleInitFun:$isEnter")
|
||||
TheRouter.get(IAcceleratorDataHolderProvider::class.java)
|
||||
?.addInitFunResult("onExecLifecycleInitFun:$isEnter")
|
||||
initResults.add("onExecLifecycleInitFun:$isEnter")
|
||||
}
|
||||
})
|
||||
QyAccelerator.getInstance().bindQyAccRelatedListener(qyListener)
|
||||
@ -105,16 +109,29 @@ class AcceleratorProviderImpl : IAcceleratorProvider {
|
||||
// 避免外部多次设置相同的token
|
||||
return
|
||||
}
|
||||
QyAccelerator.getInstance().setQyUserToken(token, setResultCallback = { isSuccess, errMsg ->
|
||||
Utils.log(LOG_TAG, "setQyUserToken:$token --isSuccess:$isSuccess --errMsg:$errMsg")
|
||||
if (isSuccess) {
|
||||
_token = token
|
||||
} else {
|
||||
// 将setToken错误事件上报的sentry,便于后期分析原因
|
||||
SentryHelper.onEventInAllChannel(SENTRY_EVENT_ID, KEY_SET_TOKEN_ERROR_MESSAGE, errMsg)
|
||||
}
|
||||
callback?.invoke(isSuccess)
|
||||
})
|
||||
fun setToken() {
|
||||
QyAccelerator.getInstance().setQyUserToken(token, setResultCallback = { isSuccess, errMsg ->
|
||||
Utils.log(LOG_TAG, "setQyUserToken:$token --isSuccess:$isSuccess --errMsg:$errMsg")
|
||||
if (isSuccess) {
|
||||
_token = token
|
||||
} else {
|
||||
// 将setToken错误事件上报的火山云,便于后期分析原因
|
||||
NewFlatLogUtils.logAcceleratorSetTokenError(initResults, errMsg ?: "")
|
||||
}
|
||||
callback?.invoke(isSuccess)
|
||||
})
|
||||
|
||||
}
|
||||
if (QyAccelerator.getInstance().checkApplicationContextIsInit()) {
|
||||
setToken()
|
||||
} else {
|
||||
// 初始化失败,再次初始化之后在setToken
|
||||
val ghVersionName = TheRouter.get(IAcceleratorDataHolderProvider::class.java)?.getGhVersionName() ?: ""
|
||||
init(EnvHelper.isDevEnv, HaloApp.getInstance(), ghVersionName)
|
||||
// 不管初始化成功还是失败,都需要再次setToken,如果失败,正常上报失败日志
|
||||
setToken()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
override fun deleteQyUserToken(): Boolean {
|
||||
@ -127,6 +144,7 @@ class AcceleratorProviderImpl : IAcceleratorProvider {
|
||||
_token = ""
|
||||
listeners.clear()
|
||||
allListener.clear()
|
||||
initResults.clear()
|
||||
return isDeleted
|
||||
}
|
||||
|
||||
@ -171,10 +189,6 @@ class AcceleratorProviderImpl : IAcceleratorProvider {
|
||||
|
||||
companion object {
|
||||
private const val LOG_TAG = "AcceleratorProviderImpl"
|
||||
private const val SENTRY_EVENT_ID = "ACCELERATOR_SET_TOKEN_ERROR"
|
||||
private const val KEY_SET_TOKEN_ERROR_MESSAGE = "set_token_error"
|
||||
private const val KEY_ACC_FAILURE_ERROR = "key_acc_failure_error"
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@ -3,7 +3,7 @@ package com.lg
|
||||
import android.content.Context
|
||||
import android.text.TextUtils
|
||||
import com.gh.gamecenter.common.base.activity.BaseActivity
|
||||
import com.gh.gamecenter.common.utils.toJson
|
||||
import com.gh.gamecenter.common.exposure.meta.MetaUtil
|
||||
import com.gh.gamecenter.core.HaloApp
|
||||
import com.gh.gamecenter.core.provider.IAcceleratorDataHolderProvider
|
||||
import com.gh.gamecenter.core.provider.IAppProvider
|
||||
@ -16,6 +16,7 @@ import io.sentry.*
|
||||
import io.sentry.android.core.SentryAndroid
|
||||
import io.sentry.android.fragment.FragmentLifecycleIntegration
|
||||
import io.sentry.protocol.Message
|
||||
import io.sentry.protocol.User
|
||||
|
||||
@com.therouter.inject.ServiceProvider
|
||||
class SentryProviderImpl : ISentryProvider {
|
||||
@ -31,6 +32,14 @@ class SentryProviderImpl : ISentryProvider {
|
||||
options.setAnrEnabled(false)
|
||||
}
|
||||
|
||||
val androidId = MetaUtil.getBase64EncodedAndroidId()
|
||||
|
||||
if (androidId.isNotEmpty()) {
|
||||
val user = User()
|
||||
user.id = androidId
|
||||
Sentry.setUser(user)
|
||||
}
|
||||
|
||||
options.setDebug(BuildConfig.DEBUG)
|
||||
options.setEnableAutoSessionTracking(true)
|
||||
options.setEnvironment(flavor)
|
||||
@ -131,23 +140,7 @@ class SentryProviderImpl : ISentryProvider {
|
||||
}
|
||||
|
||||
Utils.log("Sentry", "$eventId + [${kv.joinToString(" , ")}]")
|
||||
Sentry.captureEvent(sentryEvent) {
|
||||
// 添加Breadcrumb
|
||||
it.addBreadcrumb(Breadcrumb().apply {
|
||||
type = "initSdk"
|
||||
category = "Init"
|
||||
this.message = "init qiyou sdk"
|
||||
level = SentryLevel.INFO
|
||||
|
||||
val iAcceleratorDataHolderProvider = TheRouter.get(IAcceleratorDataHolderProvider::class.java)
|
||||
if (iAcceleratorDataHolderProvider != null) {
|
||||
val initFunResults = iAcceleratorDataHolderProvider.getInitFunResults()
|
||||
initFunResults.forEachIndexed { index, result ->
|
||||
setData("init_sdk_fun_$index", result)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
Sentry.captureEvent(sentryEvent)
|
||||
}
|
||||
|
||||
override fun captureException(e: Throwable) {
|
||||
|
||||
@ -44,7 +44,7 @@ object EnvHelper {
|
||||
fun getHost(): String {
|
||||
val buildConfig = TheRouter.get(IBuildConfigProvider::class.java)
|
||||
return if (!PackageFlavorHelper.IS_TEST_FLAVOR) {
|
||||
buildConfig?.getApiHost() ?: ""
|
||||
buildConfig?.getApiHost() ?: "https://and-api.ghzs6.com/v5d5d0/"
|
||||
} else {
|
||||
if (isDevEnv) {
|
||||
buildConfig?.getDevApiHost() ?: ""
|
||||
@ -58,7 +58,7 @@ object EnvHelper {
|
||||
fun getVHost(): String {
|
||||
val buildConfig = TheRouter.get(IBuildConfigProvider::class.java)
|
||||
return if (!PackageFlavorHelper.IS_TEST_FLAVOR) {
|
||||
buildConfig?.getVDevApiHost() ?: ""
|
||||
buildConfig?.getVApiHost() ?: "https://app-api.796697.com"
|
||||
} else {
|
||||
if (isDevEnv) {
|
||||
buildConfig?.getVDevApiHost() ?: ""
|
||||
@ -72,7 +72,7 @@ object EnvHelper {
|
||||
fun getNewHost(): String {
|
||||
val buildConfig = TheRouter.get(IBuildConfigProvider::class.java)
|
||||
return if (!PackageFlavorHelper.IS_TEST_FLAVOR) {
|
||||
buildConfig?.getNewApiHost() ?: ""
|
||||
buildConfig?.getNewApiHost() ?: "https://app-api.ghzs6.com/"
|
||||
} else {
|
||||
if (isDevEnv) {
|
||||
buildConfig?.getNewDevApiHost() ?: ""
|
||||
|
||||
@ -1179,10 +1179,15 @@ fun DownloadEntity.putGameCategory(gameCategory: String) {
|
||||
|
||||
inline fun doOnMainProcessOnly(f: () -> Unit) {
|
||||
val buildConfig = TheRouter.get(IBuildConfigProvider::class.java)
|
||||
val packageUtilsConfig = TheRouter.get(IPackageUtilsProvider::class.java)
|
||||
val processName = packageUtilsConfig?.obtainProcessName()
|
||||
val processName = ProcessUtil.getCurrentProcessName()
|
||||
var applicationId = buildConfig?.getApplicationId()
|
||||
|
||||
if (processName == null || buildConfig?.getApplicationId() == processName) {
|
||||
// buildConfig 为空的兜底方案,至于你说为什么会为空,我也不知道
|
||||
if (applicationId.isNullOrEmpty()) {
|
||||
applicationId = HaloApp.getInstance().packageName ?: "com.gh.gamecenter"
|
||||
}
|
||||
|
||||
if (processName == null || applicationId == processName) {
|
||||
f.invoke()
|
||||
} else {
|
||||
tryWithDefaultCatch {
|
||||
|
||||
@ -337,6 +337,7 @@ object SensorsBridge {
|
||||
private const val EVENT_CALENDAR_PERMISSIONS_DIALOG_SHOW = "CalendarPermissionsDialogShow"
|
||||
private const val EVENT_CALENDAR_PERMISSIONS_DIALOG_CLICK = "CalendarPermissionsDialogClick"
|
||||
private const val CALENDAR_PERMISSIONS_DIALOG_RESULT = "CalendarPermissionsDialogResult"
|
||||
private const val EVENT_GAME_DETAIL_VIDEO_CLICK= "GameDetailVideoClick"
|
||||
|
||||
private var mIsSensorsEnabled = false
|
||||
|
||||
@ -1291,18 +1292,21 @@ object SensorsBridge {
|
||||
* @param gameId 游戏ID
|
||||
* @param gameName 游戏名称
|
||||
* @param gameType 游戏类型
|
||||
* @param exceptionDigest 异常摘要
|
||||
* @see EVENT_GAME_DEPRESSION_FAILED
|
||||
*/
|
||||
@JvmStatic
|
||||
fun trackGameDecompressionFailed(
|
||||
gameId: String,
|
||||
gameName: String,
|
||||
gameType: String
|
||||
gameType: String,
|
||||
exceptionDigest: String,
|
||||
) {
|
||||
val json = json {
|
||||
KEY_GAME_ID to gameId
|
||||
KEY_GAME_NAME to gameName
|
||||
KEY_GAME_TYPE to gameType
|
||||
"exception_digest" to exceptionDigest
|
||||
}
|
||||
|
||||
trackEvent(EVENT_GAME_DEPRESSION_FAILED, json)
|
||||
@ -5340,4 +5344,37 @@ object SensorsBridge {
|
||||
}
|
||||
trackEvent(CALENDAR_PERMISSIONS_DIALOG_RESULT, json)
|
||||
}
|
||||
|
||||
/**
|
||||
* 事件ID:GameDetailVideoClick
|
||||
* 事件名称:游戏详情视频点击事件
|
||||
*/
|
||||
fun trackGameDetailVideoClick(
|
||||
gameName: String,
|
||||
gameId: String,
|
||||
gameType: String,
|
||||
lastPageName: String,
|
||||
lastPageId: String,
|
||||
action: String,
|
||||
playType: String,
|
||||
isFullScreen: Boolean,
|
||||
sequence: Int,
|
||||
tabName: String,
|
||||
playLength: String
|
||||
) {
|
||||
val json = json {
|
||||
KEY_GAME_ID to gameId
|
||||
KEY_GAME_NAME to gameName
|
||||
KEY_GAME_TYPE to gameType
|
||||
KEY_LAST_PAGE_ID to lastPageId
|
||||
KEY_LAST_PAGE_NAME to lastPageName
|
||||
KEY_ACTION to action
|
||||
KEY_PLAY_TYPE to playType
|
||||
"is_full_screen" to isFullScreen
|
||||
KEY_SEQUENCE to sequence
|
||||
"tab_name" to tabName
|
||||
"play_length" to playLength
|
||||
}
|
||||
trackEvent(EVENT_GAME_DETAIL_VIDEO_CLICK, json)
|
||||
}
|
||||
}
|
||||
@ -105,6 +105,7 @@ class SegmentedFilterView @JvmOverloads constructor(context: Context, attrs: Att
|
||||
if (mContainerBackground != null) background = mContainerBackground
|
||||
mContainer = FrameLayout(context)
|
||||
mIndicator = View(context).apply {
|
||||
visibility = View.GONE
|
||||
background = mIndicatorBackground
|
||||
}
|
||||
mRadioGroup = RadioGroup(context).apply {
|
||||
@ -127,6 +128,7 @@ class SegmentedFilterView @JvmOverloads constructor(context: Context, attrs: Att
|
||||
mIndicator.updateLayoutParams<ViewGroup.LayoutParams> {
|
||||
width = mRadioGroup.getChildAt(defaultCheckPosition)?.width ?: mItemWidth
|
||||
}
|
||||
mIndicator.visibility = View.VISIBLE
|
||||
setChecked(defaultCheckPosition)
|
||||
}
|
||||
}
|
||||
|
||||
@ -4,9 +4,7 @@ interface IAcceleratorDataHolderProvider {
|
||||
|
||||
fun setVipEntity(vip: Any)
|
||||
|
||||
fun addInitFunResult(result: String)
|
||||
|
||||
fun getInitFunResults(): List<String>
|
||||
fun getGhVersionName(): String
|
||||
|
||||
fun clear()
|
||||
}
|
||||
@ -13,6 +13,8 @@ object NewFlatLogUtils {
|
||||
private const val KEY_GAME_ID = "game_id"
|
||||
private const val KEY_GAME_NAME = "game_name"
|
||||
private const val KEY_TEXT = "text"
|
||||
private const val KEY_ERROR = "error"
|
||||
private const val KEY_INIT_SDK_FUN = "init_sdk_fun"
|
||||
|
||||
private fun log(jsonObject: JSONObject, logStore: String = "event", uploadImmediately: Boolean = false) {
|
||||
Utils.log("NewFlatLogUtils", jsonObject.toString(4))
|
||||
@ -52,4 +54,14 @@ object NewFlatLogUtils {
|
||||
}
|
||||
log(json)
|
||||
}
|
||||
|
||||
@JvmStatic
|
||||
fun logAcceleratorSetTokenError(initResults: List<String>, error: String) {
|
||||
json {
|
||||
KEY_EVENT to "accelerator_set_token_error"
|
||||
KEY_ERROR to error
|
||||
KEY_INIT_SDK_FUN to initResults.toString()
|
||||
parseAndPutMeta().invoke(this)
|
||||
}.let(::log)
|
||||
}
|
||||
}
|
||||
2
vasdk
2
vasdk
Submodule vasdk updated: 932474708c...2ee1c3d532
Reference in New Issue
Block a user