Merge remote-tracking branch 'origin/release' into dev

# Conflicts:
#	dependencies.gradle
This commit is contained in:
chenjuntao
2025-05-14 09:25:17 +08:00
17 changed files with 155 additions and 42 deletions

View File

@ -55,6 +55,8 @@ public class DetailDownloadUtils {
}
viewHolder.setSpeedViewsVisible(false);
// 默认为显示状态
viewHolder.getDownloadPb().setVisibility(View.VISIBLE);
// 根据预置的配置更新 ViewHolder 的状态 (譬如青少年模式、下载内容为空等)
if (updateViewHolderWithPredefinedConfig(viewHolder, gameEntity)) {

View File

@ -217,7 +217,7 @@ class DetailViewHolder(
}
private fun restoreDialogFragment() {
val gamePermissionDialogFragment = (context as AppCompatActivity).supportFragmentManager.findFragmentByTag(
val gamePermissionDialogFragment = (context.getActivity() as? AppCompatActivity)?.supportFragmentManager?.findFragmentByTag(
GamePermissionDialogFragment::class.java.name
) as DialogFragment?
gamePermissionDialogFragment?.dismissAllowingStateLoss()
@ -233,7 +233,6 @@ class DetailViewHolder(
getDownloadBtnText(context, gameEntity, false, true, PluginLocation.only_game)
when {
localText.contains(com.gh.gamecenter.feature.R.string.update.toResString()) -> { // 本地游戏需要更新
localDownloadButton?.goneIf(true)
localDownloadContainer?.goneIf(true)
downloadPb.goneIf(true)
overlayTv?.goneIf(true)
@ -250,7 +249,6 @@ class DetailViewHolder(
localText.contains(com.gh.gamecenter.feature.R.string.launch.toResString()) && downloadText == "更新" -> { // 畅玩游戏需要更新:显示 加速/更新
localDownloadContainer?.goneIf(true)
localDownloadButton?.goneIf(true)
downloadPb.goneIf(true)
overlayTv?.goneIf(true)
@ -263,7 +261,6 @@ class DetailViewHolder(
}
localText.contains(com.gh.gamecenter.feature.R.string.launch.toResString()) -> { // 本地游戏为启动状态:显示 加速/畅玩
localDownloadButton?.goneIf(true)
localDownloadContainer?.goneIf(true)
downloadPb.goneIf(true)
overlayTv?.goneIf(true)
@ -288,20 +285,20 @@ class DetailViewHolder(
val downloadText = getDownloadBtnText(context, gameEntity, false, false, PluginLocation.only_game)
when {
downloadText.contains(com.gh.gamecenter.feature.R.string.launch.toResString()) -> {
localDownloadButton?.goneIf(true)
localDownloadContainer?.goneIf(true)
downloadPb.goneIf(true)
true
}
downloadText == com.gh.gamecenter.feature.R.string.launch.toResString() -> true
downloadText.contains(R.string.update.toResString()) -> true
else -> false
}
}
else -> false
}
it.checkIfShowSpeedUi(showSpeedUi)
it.checkIfShowSpeedUi(showSpeedUi, showDualDownloadButton)
}
}

View File

@ -55,6 +55,8 @@ class GameDetailAcceleratorUiHelper(private val binding: DetailDownloadItemBindi
private var hasAnyAcctRecord = false
private var showDualDownloadButton: Boolean = false
private val accelerationListener = object : OnAccelerateListener {
override fun onStateChanged(state: AccelerateState) {
when (state) {
@ -131,13 +133,17 @@ class GameDetailAcceleratorUiHelper(private val binding: DetailDownloadItemBindi
val isCurrentGameAccelerating = AcceleratorDataHolder.instance.isCurrentGameAccelerating(game.id)
when {
isCurrentGameAccelerating -> {// 如果当前游戏正处于加速状态,则需要隐藏当前下载按钮
binding.detailProgressbar.goneIf(true)
}
if (!showDualDownloadButton) {
when {
isCurrentGameAccelerating -> {// 如果当前游戏正处于加速状态,则需要隐藏当前下载按钮
binding.detailProgressbar.goneIf(true)
}
binding.detailProgressbar.text == "更新" -> { // 游戏没有处于加速状态,如果 下载按钮为 “更新” 状态,则需要显示出来
binding.detailProgressbar.goneIf(false)
binding.detailProgressbar.text == "更新" -> { // 游戏没有处于加速状态,如果 下载按钮为 “更新” 状态,则需要显示出来
binding.detailProgressbar.setBackgroundResource(com.gh.gamecenter.common.R.drawable.bg_common_button_light_fill_blue)
binding.detailProgressbar.setTextColor(com.gh.gamecenter.common.R.color.text_theme.toColor(context))
binding.detailProgressbar.goneIf(false)
}
}
}
@ -152,7 +158,8 @@ class GameDetailAcceleratorUiHelper(private val binding: DetailDownloadItemBindi
} ?: R.string.network_acceleration.toResString()
}
fun checkIfShowSpeedUi(show: Boolean) {
fun checkIfShowSpeedUi(show: Boolean, showDualDownloadButton: Boolean) {
this.showDualDownloadButton = showDualDownloadButton
if (!isInit) {
return
}

View File

@ -86,7 +86,8 @@ class GameDetailFragment : LazyFragment(), IScrollable {
GameDetailCoverAdapter(
requireContext(),
this@GameDetailFragment,
viewModel
viewModel,
scrollCalculatorHelper
) {
binding.coverSfv.isVisible = shouldShowCoverFilter && it
}

View File

@ -23,6 +23,7 @@ import com.gh.gamecenter.databinding.ItemGameCoverVideoBinding
import com.gh.gamecenter.gamedetail.GameDetailViewModel
import com.gh.gamecenter.gamedetail.detail.GameDetailFragment
import com.gh.gamecenter.gamedetail.entity.CoverEntity
import com.gh.gamecenter.gamedetail.video.GameDetailScrollCalculatorHelper
import com.gh.gamecenter.gamedetail.video.TopVideoView
import com.lightgame.adapter.BaseRecyclerAdapter
import com.shuyu.gsyvideoplayer.builder.GSYVideoOptionBuilder
@ -33,6 +34,7 @@ class GameDetailCoverAdapter(
context: Context,
private val fragment: GameDetailFragment,
private val viewModel: GameDetailViewModel,
private val scrollCalculatorHelper: GameDetailScrollCalculatorHelper,
private val showOrHideCoverFilter: ((Boolean) -> Unit)
) : BaseRecyclerAdapter<RecyclerView.ViewHolder>(context) {
@ -108,6 +110,14 @@ class GameDetailCoverAdapter(
.setAutoFullWithSize(true)
.setDismissControlTime(5000)
.setVideoAllCallBack(object : GSYSampleCallBack() {
override fun onClickStartIcon(url: String?, vararg objects: Any?) {
scrollCalculatorHelper.currentPlayer = holder.binding.player
}
override fun onClickResume(url: String?, vararg objects: Any?) {
scrollCalculatorHelper.currentPlayer = holder.binding.player
}
override fun onQuitFullscreen(url: String?, vararg objects: Any) {
orientationUtils.backToProtVideo()
holder.binding.player.uploadVideoStreamingPlaying("退出全屏")
@ -117,6 +127,7 @@ class GameDetailCoverAdapter(
holder.binding.player.viewModel = viewModel
holder.binding.player.showOrHideCoverFilter = showOrHideCoverFilter
holder.binding.player.scrollCalculatorHelper = scrollCalculatorHelper
holder.binding.player.video = topVideo
holder.binding.player.updateThumb(topVideo.poster)

View File

@ -30,7 +30,9 @@ import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.view.CustomLinkMovementMethod
import com.gh.gamecenter.common.view.DrawableView
import com.gh.gamecenter.core.utils.*
import com.gh.gamecenter.core.utils.CenterImageSpan
import com.gh.gamecenter.core.utils.NumberUtils
import com.gh.gamecenter.core.utils.SpanBuilder
import com.gh.gamecenter.databinding.RatingCommentItemBinding
import com.gh.gamecenter.entity.RatingComment
import com.gh.gamecenter.feature.entity.GameEntity
@ -249,7 +251,7 @@ class RatingCommentItemViewHolder(val binding: RatingCommentItemBinding, val pat
if (game.getApk().size > 0 && game.getApk()[0].version == commentData.gameVersion) {
version.text = "当前版本"
} else {
version.text = ("版本:" + commentData.gameVersion)
version.text = commentData.gameVersion
}
}
}

View File

@ -7,6 +7,7 @@ import android.text.Spanned
import android.text.TextPaint
import android.text.method.LinkMovementMethod
import android.text.style.ClickableSpan
import android.view.Gravity
import android.view.LayoutInflater
import android.view.View
import android.widget.LinearLayout
@ -15,6 +16,7 @@ import android.widget.TextView
import androidx.constraintlayout.widget.ConstraintLayout
import androidx.constraintlayout.widget.ConstraintSet
import androidx.core.content.ContextCompat
import androidx.core.view.updateLayoutParams
import com.gh.common.util.*
import com.gh.common.util.NewFlatLogUtils
import com.gh.common.util.NewLogUtils
@ -27,7 +29,8 @@ import com.gh.gamecenter.common.constant.Constants
import com.gh.gamecenter.common.constant.EntranceConsts
import com.gh.gamecenter.common.utils.*
import com.gh.gamecenter.common.view.DrawableView
import com.gh.gamecenter.core.utils.*
import com.gh.gamecenter.core.utils.NumberUtils
import com.gh.gamecenter.core.utils.SpanBuilder
import com.gh.gamecenter.databinding.ItemArticleDetailCommentBinding
import com.gh.gamecenter.entity.RatingComment
import com.gh.gamecenter.gamedetail.rating.edit.RatingEditActivity
@ -165,7 +168,36 @@ class RatingDetailCommentItemViewHolder(val binding: ItemArticleDetailCommentBin
if (game != null && game.getApk().size > 0 && game.getApk()[0].version == commentData.gameVersion) {
version.text = "当前版本"
} else {
version.text = ("版本:" + commentData.gameVersion)
version.text = commentData.gameVersion
}
version.buttonDrawable = R.drawable.ic_version.toDrawable(context)
version.post {
ConstraintSet().apply {
clone(bottomContainer)
if ((version.layout?.lineCount ?: 1) > 1) {
version.gravity = Gravity.TOP
connect(version.id, ConstraintSet.START, device.id, ConstraintSet.START)
connect(version.id, ConstraintSet.TOP, device.id, ConstraintSet.BOTTOM, 6F.dip2px())
connect(version.id, ConstraintSet.BOTTOM, ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM, 16F.dip2px())
connect(device.id, ConstraintSet.BOTTOM, version.id, ConstraintSet.TOP)
connect(device.id, ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.TOP, 16F.dip2px())
clear(device.id, ConstraintSet.END)
clear(likeCountTv.id, ConstraintSet.TOP)
connect(likeCountTv.id, ConstraintSet.BOTTOM, ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM, 4F.dip2px())
bottomContainer.updateLayoutParams<ConstraintLayout.LayoutParams> { height = ConstraintLayout.LayoutParams.WRAP_CONTENT }
} else {
version.gravity = Gravity.CENTER_VERTICAL
connect(version.id, ConstraintSet.START, device.id, ConstraintSet.END)
connect(version.id, ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.TOP, 0)
connect(version.id, ConstraintSet.BOTTOM, ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM, 0)
connect(device.id, ConstraintSet.BOTTOM, ConstraintSet.PARENT_ID, ConstraintSet.BOTTOM)
connect(device.id, ConstraintSet.END, version.id, ConstraintSet.START)
connect(device.id, ConstraintSet.TOP, ConstraintSet.PARENT_ID, ConstraintSet.TOP, 0)
connect(likeCountTv.id, ConstraintSet.TOP, timeTv.id, ConstraintSet.TOP, 0)
connect(likeCountTv.id, ConstraintSet.BOTTOM, timeTv.id, ConstraintSet.BOTTOM, 0)
bottomContainer.updateLayoutParams<ConstraintLayout.LayoutParams> { height = 48F.dip2px() }
}
}.applyTo(bottomContainer)
}
if (commentData.me.isCommented) {

View File

@ -50,6 +50,7 @@ class TopVideoView @JvmOverloads constructor(context: Context, attrs: AttributeS
private var mLastGetContentLengthTime = 0L
var showOrHideCoverFilter: ((Boolean) -> Unit)? = null
var scrollCalculatorHelper: GameDetailScrollCalculatorHelper? = null
init {
post {
@ -256,6 +257,7 @@ class TopVideoView @JvmOverloads constructor(context: Context, attrs: AttributeS
// 不需要弹弹窗,直接播放
override fun showWifiDialog() {
scrollCalculatorHelper?.currentPlayer = this
startPlayLogic(false)
//val trafficVideo = PreferenceManager.getDefaultSharedPreferences(context).getBoolean(SettingsFragment.TRAFFIC_VIDEO_SP_KEY, false)
//if (trafficVideo) {

View File

@ -527,7 +527,7 @@ class SearchGameResultAdapter(
for (key in positionAndPackageMap.keys) {
if (key.contains(download.packageName) && key.contains(download.gameId)) {
val position = positionAndPackageMap[key]
if (position != null && getItemViewType(position) == ItemViewType.GAME_SUBJECT) {
if (position != null && position < itemCount && getItemViewType(position) == ItemViewType.GAME_SUBJECT) {
val view = _recyclerView?.layoutManager?.findViewByPosition(position)
val adapter = view?.findViewById<RecyclerView>(R.id.subjectRv)?.adapter
if (adapter != null && adapter is SearchSubjectAdapter) {

View File

@ -97,9 +97,11 @@ class SearchGameResultViewModel(
// 数据源来自于第三方的专题列表,包括 CPM 专题和 DSP 专题
val thirdPartySearchSubjectList = mutableListOf<SearchSubjectEntity>()
// 避免重复添加同一个 location 位置的专题
for (item in mutableList) {
if (!mSearchSubjects.any { it.location == item.location }) {
// 避免同一个位置重复的专题
if (!mSearchSubjects.any {
it.location == item.location && it.columnId == item.columnId
}) {
mSearchSubjects.add(item)
}
}

View File

@ -0,0 +1,14 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="12dp"
android:height="12dp"
android:viewportWidth="12"
android:viewportHeight="12">
<path
android:strokeWidth="1"
android:pathData="M4,1.5L8,1.5A1.5,1.5 0,0 1,9.5 3L9.5,9A1.5,1.5 0,0 1,8 10.5L4,10.5A1.5,1.5 0,0 1,2.5 9L2.5,3A1.5,1.5 0,0 1,4 1.5z"
android:fillColor="#00000000"
android:strokeColor="@color/text_tertiary"/>
<path
android:pathData="M5.5,3L6.5,3A0.5,0.5 0,0 1,7 3.5L7,3.5A0.5,0.5 0,0 1,6.5 4L5.5,4A0.5,0.5 0,0 1,5 3.5L5,3.5A0.5,0.5 0,0 1,5.5 3z"
android:fillColor="@color/text_tertiary"/>
</vector>

View File

@ -0,0 +1,19 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="12dp"
android:height="12dp"
android:viewportWidth="12"
android:viewportHeight="12">
<path
android:strokeWidth="1"
android:pathData="M7.5,5L5.5,7.5L5,5H4.5"
android:strokeLineJoin="round"
android:fillColor="#00000000"
android:strokeColor="@color/text_tertiary"
android:strokeLineCap="round"/>
<path
android:strokeWidth="1"
android:pathData="M3.5,2H8.5C9.328,2 10,2.672 10,3.5V8.5C10,9.328 9.328,10 8.5,10H3.5C2.672,10 2,9.328 2,8.5V3.5C2,2.672 2.672,2 3.5,2Z"
android:fillColor="#00000000"
android:strokeColor="@color/text_tertiary"
android:strokeLineCap="round"/>
</vector>

View File

@ -415,15 +415,16 @@
android:id="@+id/device"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:drawableLeft="@drawable/rating_phone_icon"
android:drawablePadding="4dp"
android:drawablePadding="2dp"
android:ellipsize="end"
android:gravity="center"
android:includeFontPadding="false"
android:maxLines="1"
android:paddingRight="8dp"
android:paddingEnd="8dp"
android:textColor="@color/text_tertiary"
android:textSize="10sp"
android:textSize="@dimen/tag_text_size"
android:visibility="gone"
app:drawableStartCompat="@drawable/ic_phone"
app:layout_constrainedWidth="true"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/version"
@ -433,19 +434,27 @@
app:layout_constraintTop_toTopOf="parent"
tools:text="小米2S" />
<TextView
<RadioButton
android:id="@+id/version"
android:layout_width="wrap_content"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginRight="8dp"
android:gravity="center"
android:layout_marginEnd="16dp"
android:button="@drawable/ic_version"
android:checked="false"
android:clickable="false"
android:gravity="center_vertical"
android:includeFontPadding="false"
android:lineSpacingExtra="2sp"
android:paddingStart="2dp"
android:textColor="@color/text_tertiary"
android:textSize="10sp"
android:textSize="@dimen/tag_text_size"
android:visibility="gone"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintEnd_toStartOf="@+id/commentCountTv"
app:layout_constraintStart_toEndOf="@+id/device"
app:layout_constraintTop_toTopOf="parent"
app:layout_goneMarginStart="8dp" />
app:layout_goneMarginStart="8dp"
tools:text="版本号" />
<TextView
android:id="@+id/likeCountTv"

View File

@ -201,14 +201,14 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:drawableLeft="@drawable/rating_phone_icon"
android:drawablePadding="4dp"
android:drawablePadding="2dp"
android:ellipsize="end"
android:gravity="center"
android:maxLines="1"
android:paddingRight="8dp"
android:paddingEnd="8dp"
android:textColor="@color/text_tertiary"
android:textSize="10sp"
android:textSize="@dimen/tag_text_size"
app:drawableStartCompat="@drawable/ic_phone"
app:layout_constrainedWidth="true"
app:layout_constraintBottom_toBottomOf="@+id/vote"
app:layout_constraintEnd_toStartOf="@+id/version"
@ -220,17 +220,23 @@
<TextView
android:id="@+id/version"
android:layout_width="wrap_content"
android:layout_width="0dp"
android:layout_height="wrap_content"
android:layout_marginEnd="8dp"
android:gravity="center"
android:layout_marginEnd="16dp"
android:drawablePadding="2dp"
android:ellipsize="end"
android:gravity="center_vertical"
android:lines="1"
android:textColor="@color/text_tertiary"
android:textSize="10sp"
android:textSize="@dimen/tag_text_size"
app:drawableStartCompat="@drawable/ic_version"
app:layout_constrainedWidth="true"
app:layout_constraintBottom_toBottomOf="@+id/vote"
app:layout_constraintEnd_toStartOf="@+id/comment"
app:layout_constraintStart_toEndOf="@id/device"
app:layout_constraintTop_toTopOf="@+id/vote"
app:layout_goneMarginStart="16dp" />
app:layout_goneMarginStart="16dp"
tools:text="版本号版本号版本号版本号版本号版本号版本号版本号" />
<TextView
android:id="@+id/comment"

View File

@ -6,6 +6,7 @@ import android.app.Activity
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.content.ContextWrapper
import android.content.res.Configuration
import android.graphics.Bitmap
import android.graphics.Canvas
@ -424,6 +425,13 @@ fun Context.ifLogin(entrance: String, action: (() -> Unit)? = null) {
checkLoginConfig?.checkLogin(this, entrance, action)
}
fun Context.getActivity(): Activity? {
return when (this) {
is Activity -> this
is ContextWrapper -> this.baseContext.getActivity()
else -> null
}
}
/**
* Gson related extensions.

View File

@ -11,6 +11,7 @@
style="@style/Base_ToolbarStyle"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:contentInsetStart="0dp"
app:contentInsetEnd="0dp"
app:contentInsetStartWithNavigation="0dp"
app:navigationIcon="@null">

View File

@ -662,7 +662,7 @@ public class UserRepository {
String userInfo = mPreferences.getString(Constants.USER_INFO_KEY, null);
if (!TextUtils.isEmpty(userInfo)) {
UserInfoEntity infoEntity = GsonUtils.fromJson(userInfo, UserInfoEntity.class);
setAcceleratorToken(infoEntity.getUserId(), null);
setAcceleratorToken(infoEntity.getUserId(), () -> null);
}
}