Merge branch 'feature-issues1087' into 'dev-4.6.0'

https://git.ghzs.com/pm/halo-app-issues/-/issues/1087

See merge request halo/assistant-android!53
This commit is contained in:
juntao
2020-12-26 11:49:59 +08:00
21 changed files with 148 additions and 38 deletions

View File

@ -13,6 +13,7 @@ data class ExposureEntity(
val gameName: String? = "",
val gameVersion: String? = "",
val sequence: Int? = 0,
val outerSequence: Int? = 0,
val platform: String? = "",
var isMirrorData: Boolean = false,
val downloadType: String? = "",

View File

@ -39,7 +39,8 @@ data class ExposureEvent(
gameName = gameEntity?.name?.removeSuffix(Constants.GAME_NAME_DECORATOR),
gameVersion = gameEntity?.gameVersion,
isMirrorData = eTrace?.firstOrNull()?.payload?.isMirrorData ?: gameEntity?.shouldUseMirrorInfo() ?: false,
sequence = gameEntity?.sequence,
sequence = eTrace?.firstOrNull()?.payload?.sequence ?: gameEntity?.sequence,
outerSequence = eTrace?.firstOrNull()?.payload?.outerSequence ?: gameEntity?.outerSequence,
platform = gameEntity?.platform,
downloadType = gameEntity?.downloadType,
downloadCompleteType = gameEntity?.downloadCompleteType,

View File

@ -606,7 +606,7 @@ fun TextView.setTextChangedListener(action: (s: CharSequence, start: Int, before
*/
fun <T> ArrayList<T>.safelyGetInRelease(index: Int): T? {
return if (index >= size) {
throwExceptionInDebug("这里触发了数组越界,请检查")
throwExceptionInDebug("这里触发了数组越界,请检查 (index $index >= size $size)")
toastInInternalRelease("这个操作可能触发闪退,请确定复现方式并联系开发处理")
null
} else {

View File

@ -88,7 +88,7 @@ object PackageInstaller {
@JvmStatic
fun getInstallIntent(context: Context, path: String): Intent {
var uri = Uri.fromFile(File(path))
val installIntent = Intent(Intent.ACTION_VIEW)
val installIntent = Intent(Intent.ACTION_INSTALL_PACKAGE)
if ("smartisan" == Build.MANUFACTURER) {
installIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
}

View File

@ -88,6 +88,7 @@ public class ImagePagerAdapter extends RecyclingPagerAdapter {
GameEntity fakeGameEntity = new GameEntity();
fakeGameEntity.setId(slideEntity.getLink());
fakeGameEntity.setName(slideEntity.getText());
fakeGameEntity.setSequence(index);
exposureEvent = ExposureEvent.createEvent(fakeGameEntity, mExposureSourceList, null, ExposureType.EXPOSURE);
}

View File

@ -94,7 +94,7 @@ class NewCatalogListAdapter(context: Context,
GameViewUtils.setLabelList(mContext, holder.binding.labelList, gameEntity.tagStyle)
gameEntity.sequence = position + 1
gameEntity.sequence = position
val sortType = mViewModel.sortType.value
val sortSize = mViewModel.sortSize.text
@ -105,7 +105,7 @@ class NewCatalogListAdapter(context: Context,
exposureSources.add(mBaseExposureSource)
exposureSources.add(ExposureSource(toolbarTitle))
exposureSources.add(ExposureSource("二级分类详情", "$selectedCatalogName+$sortType+$sortSize"))
gameEntity.sequence = position + 1
gameEntity.sequence = position
val event = ExposureEvent.createEvent(gameEntity, exposureSources, null, ExposureType.EXPOSURE)
mExposureEventSparseArray.put(position, event)

View File

@ -111,7 +111,7 @@ class SpecialCatalogAdapter(context: Context, private val mCatalogViewModel: Cat
var exposureEvent: ExposureEvent? = null
if (imageEntity.link.type == "game") {
exposureEvent = ExposureEvent.createEvent(
GameEntity(id = imageEntity.link.link),
GameEntity(id = imageEntity.link.link).apply { outerSequence = mEntityList[position].position },
listOf(mCatalogViewModel.basicExposureSource, ExposureSource("精选页图片", "")))
mExposureEventSparseArray.append(position, exposureEvent)
}
@ -144,12 +144,16 @@ class SpecialCatalogAdapter(context: Context, private val mCatalogViewModel: Cat
val subject = mEntityList[position].subject!!
val exposureList = arrayListOf<ExposureEvent>()
for (game in subject.link.data) {
for ((index, game) in subject.link.data.withIndex()) {
game.sequence = index
game.subjectName = subject.link.text
game.outerSequence = mEntityList[position].position
val exposureEvent = ExposureEvent.createEvent(game,
listOf(mCatalogViewModel.basicExposureSource, ExposureSource("精选页专题", subject.link.text ?: "")))
exposureList.add(exposureEvent)
game.exposureEvent = exposureEvent
game.subjectName = subject.link.text
}
mEntityList[position].exposureEventList = exposureList

View File

@ -89,7 +89,7 @@ class NewCategoryListAdapter(context: Context,
val padTop = if (position == 0) 16F.dip2px() else 8F.dip2px()
holder.itemView.setPadding(16F.dip2px(), padTop, 16F.dip2px(), 8F.dip2px())
gameEntity.sequence = position + 1
gameEntity.sequence = position
val sortType = if ("download:-1" == mViewModel.getSortType()) "最热" else "最新"
val toolbarTitle = mViewModel.title
@ -99,7 +99,7 @@ class NewCategoryListAdapter(context: Context,
val exposureSources = ArrayList<ExposureSource>()
exposureSources.add(ExposureSource(categoryTitle, selectedCategoryName))
exposureSources.add(ExposureSource("二级分类", "$selectedCategoryName+$sortType"))
gameEntity.sequence = position + 1
gameEntity.sequence = position
val event = ExposureEvent.createEvent(gameEntity, exposureSources, null, ExposureType.EXPOSURE)
mExposureEventSparseArray.put(position, event)

View File

@ -28,7 +28,11 @@ data class AmwayCommentEntity(
var nameSuffix: String? = "",
@SerializedName(value = "new_tag_style")
var tag: List<TagStyleEntity>? = arrayListOf(),
var star: Float) : Parcelable {
var star: Float,
// 曝光用的位置
var sequence: Int = 0,
var outerSequence: Int = 0) : Parcelable {
@IgnoredOnParcel
val name: String?
@ -42,6 +46,9 @@ data class AmwayCommentEntity(
gameEntity.rawIcon = rawIcon
gameEntity.iconSubscript = iconSubscript
gameEntity.platform = ""
gameEntity.sequence = sequence
gameEntity.outerSequence = outerSequence
return gameEntity
}
}

View File

@ -109,6 +109,8 @@ data class GameEntity(
var des: String? = null,
// 用来标记在专题中的序号,仅用于曝光记录
var sequence: Int? = -1,
// 用来标记在外部页面中的序号,仅用于曝光记录,具体细节可见 https://git.ghzs.com/pm/halo-app-issues/-/issues/1087
var outerSequence: Int? = -1,
// 用来标记平台名称,仅用于曝光记录
var platform: String? = "",

View File

@ -430,6 +430,8 @@ class GameViewModel(application: Application, var blockData: SubjectRecommendEnt
val gameEntity = data[0]
if (gameEntity.id.isNullOrEmpty()) gameEntity.id = gameEntity.link ?: ""
appendSequenceToSubjectGame(subjectEntity, index)
// 图片专题样式(后台操作->只显示(滑动))
if (data[0].type == "column" && subjectEntity.type == "image_slide") {
itemDataImage.imageSlide = gameEntity
@ -453,6 +455,8 @@ class GameViewModel(application: Application, var blockData: SubjectRecommendEnt
mItemDataListCache.add(getBlankSpacingItem())
}
appendSequenceToSubjectGame(subjectEntity, index)
itemDataHead.columnHead = subjectEntity
mItemDataListCache.add(itemDataHead)
}
@ -462,6 +466,8 @@ class GameViewModel(application: Application, var blockData: SubjectRecommendEnt
itemVerticalSlide.verticalSlide = subjectEntity
mItemDataListCache.add(itemVerticalSlide)
appendSequenceToSubjectGame(subjectEntity, index)
for (i in 0 until data.size) {
val game = data[i]
if (!game.image.isNullOrEmpty()) continue
@ -481,6 +487,7 @@ class GameViewModel(application: Application, var blockData: SubjectRecommendEnt
if (subjectEntity.type == "game_horizontal_slide") {
val itemHorizontalSlide = GameItemData()
itemHorizontalSlide.horizontalSlide = subjectEntity
appendSequenceToSubjectGame(subjectEntity, index)
mItemDataListCache.add(itemHorizontalSlide)
continue
}
@ -488,6 +495,7 @@ class GameViewModel(application: Application, var blockData: SubjectRecommendEnt
if (subjectEntity.type == "game_horizontal") {
val itemDataSubject = GameItemData()
itemDataSubject.horizontalColumn = subjectEntity
appendSequenceToSubjectGame(subjectEntity, index)
mItemDataListCache.add(itemDataSubject)
continue
}
@ -495,6 +503,7 @@ class GameViewModel(application: Application, var blockData: SubjectRecommendEnt
if (subjectEntity.type == "column_collection") {
val itemColumnCollection = GameItemData()
itemColumnCollection.columnCollection = subjectEntity
appendSequenceToSubjectGame(subjectEntity, index)
mItemDataListCache.add(itemColumnCollection)
continue
}
@ -502,10 +511,11 @@ class GameViewModel(application: Application, var blockData: SubjectRecommendEnt
if (subjectEntity.type == "gallery") {
val itemItemData = GameItemData()
itemItemData.gallery = subjectEntity
appendSequenceToSubjectGame(subjectEntity, index)
// 小于7就不要展示了
if (subjectEntity.data != null && subjectEntity.data!!.size >= 7) {
for ((index, game) in subjectEntity.data!!.withIndex()) {
game.sequence = index + 1
game.sequence = index
}
mItemDataListCache.add(itemItemData)
}
@ -515,10 +525,11 @@ class GameViewModel(application: Application, var blockData: SubjectRecommendEnt
if (subjectEntity.type == "gallery_slide") {
val itemItemData = GameItemData()
itemItemData.gallerySlide = subjectEntity
appendSequenceToSubjectGame(subjectEntity, index)
// 小于3就不要滚动了
if (subjectEntity.data != null && subjectEntity.data!!.size > 3) {
for ((index, game) in subjectEntity.data!!.withIndex()) {
game.sequence = index + 1
game.sequence = index
}
mItemDataListCache.add(itemItemData)
}
@ -545,6 +556,7 @@ class GameViewModel(application: Application, var blockData: SubjectRecommendEnt
game.sequence = i
itemDataGame.game = game
mItemDataListCache.add(itemDataGame)
appendSequenceToSubjectGame(subjectEntity, index)
addGamePositionAndPackage(game)
}
}
@ -577,6 +589,15 @@ class GameViewModel(application: Application, var blockData: SubjectRecommendEnt
mOffsetMap.clear()
}
private fun appendSequenceToSubjectGame(subject: SubjectEntity, outerPosition: Int) {
subject.data?.let {
for ((index, game) in it.withIndex()) {
game.sequence = index
game.outerSequence = outerPosition
}
}
}
class Factory(val mApplication: Application, val blockData: SubjectRecommendEntity?) : ViewModelProvider.NewInstanceFactory() {
override fun <T : ViewModel> create(modelClass: Class<T>): T {
return GameViewModel(mApplication, blockData) as T

View File

@ -14,7 +14,6 @@ import com.gh.gamecenter.databinding.GameHorizontalListBinding
import com.gh.gamecenter.entity.GameEntity
import com.gh.gamecenter.entity.SubjectEntity
class GameHorizontalSlideListViewHolder(val binding: GameHorizontalListBinding) : BaseRecyclerViewHolder<GameEntity>(binding.root) {
private var mScrollListener: RecyclerView.OnScrollListener? = null

View File

@ -10,10 +10,7 @@ import com.gh.common.exposure.ExposureEvent
import com.gh.common.exposure.ExposureSource
import com.gh.common.exposure.ExposureType
import com.gh.common.exposure.IExposable
import com.gh.common.util.DirectUtils
import com.gh.common.util.MtaHelper
import com.gh.common.util.dip2px
import com.gh.common.util.goneIf
import com.gh.common.util.*
import com.gh.gamecenter.AboutActivity
import com.gh.gamecenter.GameDetailActivity
import com.gh.gamecenter.R
@ -171,7 +168,7 @@ class HomeFragmentAdapter(context: Context,
val intent = RatingReplyActivity.getIntent(mContext, amway.game.id, amway.comment.id, false, path, "")
mContext.startActivity(intent)
} else {
GameDetailActivity.startGameDetailActivity(mContext, amway.game.id, path, homeItemData.exposureEventList!![itemPosition])
GameDetailActivity.startGameDetailActivity(mContext, amway.game.id, path, homeItemData.exposureEventList?.safelyGetInRelease(itemPosition))
}
}

View File

@ -315,8 +315,9 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) {
if (linkType == "game" || linkType == "video") {
val attachGame = HomeItemData()
attachGame.blockPosition = i + 1
attachGame.blockPosition = i
attachGame.attachGame = homeContent
attachGame.attachGame?.linkGame?.outerSequence = attachGame.blockPosition
mSnapshotItemList.add(attachGame)
} else if (linkType == "top_game_comment") {
val head = HomeItemData()
@ -325,8 +326,13 @@ class HomeViewModel(application: Application) : AndroidViewModel(application) {
mSnapshotItemList.add(head)
val amway = HomeItemData()
amway.blockPosition = i + 1
amway.amway = homeContent.linkTopGameComment
amway.blockPosition = i
amway.amway = homeContent.linkTopGameComment?.apply {
for ((index, amwayEntity) in this.withIndex()) {
amwayEntity.game.sequence = index
amwayEntity.game.outerSequence = i
}
}
mSnapshotItemList.add(amway)
} else if (linkType == "column"
|| linkType == "column_collection"

View File

@ -523,7 +523,8 @@ class LegacyHomeFragmentAdapterAssistant(private var mContext: Context,
}
val exposureList = arrayListOf<ExposureEvent>()
for (game in pluginList!!) {
for ((index, game) in pluginList!!.withIndex()) {
game.sequence = index
val event = ExposureEvent.createEvent(gameEntity = game, source = listOf(mBasicExposureSource, ExposureSource("插件化", "")))
game.exposureEvent = event
exposureList.add(event)

View File

@ -26,6 +26,8 @@ object LegacyHomeSubjectTransformer {
val gameEntity = data[0]
if (gameEntity.id.isEmpty()) gameEntity.id = gameEntity.link ?: ""
gameEntity.outerSequence = blockPosition + 1
// 图片专题样式(后台操作->只显示(滑动))
if (data[0].type == "column" && subjectEntity.type == "image_slide") {
itemDataImage.imageSlide = gameEntity
@ -71,6 +73,8 @@ object LegacyHomeSubjectTransformer {
isOrder = subjectEntity.isOrder,
briefStyle = subjectEntity.briefStyle,
isShowSuffix = subjectEntity.showSuffix)
game.outerSequence = blockPosition
game.sequence = i
addGamePositionAndPackage(game)
}
@ -81,6 +85,7 @@ object LegacyHomeSubjectTransformer {
val itemHorizontalSlide = newItemInstance()
itemHorizontalSlide.blockPosition = blockPosition + 1
itemHorizontalSlide.horizontalSlide = subjectEntity
appendSequenceToSubjectGame(subjectEntity, blockPosition)
itemList.add(itemHorizontalSlide)
return
}
@ -89,6 +94,7 @@ object LegacyHomeSubjectTransformer {
val itemDataSubject = newItemInstance()
itemDataSubject.blockPosition = blockPosition + 1
itemDataSubject.horizontalColumn = subjectEntity
appendSequenceToSubjectGame(subjectEntity, blockPosition)
itemList.add(itemDataSubject)
return
}
@ -97,6 +103,7 @@ object LegacyHomeSubjectTransformer {
val itemColumnCollection = newItemInstance()
itemColumnCollection.blockPosition = blockPosition + 1
itemColumnCollection.columnCollection = subjectEntity
appendSequenceToSubjectGame(subjectEntity, blockPosition)
itemList.add(itemColumnCollection)
return
}
@ -107,9 +114,7 @@ object LegacyHomeSubjectTransformer {
itemItemData.blockPosition = blockPosition + 1
// 小于7就不要展示了
if (subjectEntity.data != null && subjectEntity.data!!.size >= 7) {
for ((index, game) in subjectEntity.data!!.withIndex()) {
game.sequence = index
}
appendSequenceToSubjectGame(subjectEntity, blockPosition)
itemList.add(itemItemData)
}
return
@ -120,9 +125,7 @@ object LegacyHomeSubjectTransformer {
itemItemData.gallerySlide = subjectEntity
// 小于3就不要滚动了
if (subjectEntity.data != null && subjectEntity.data!!.size > 3) {
for ((index, game) in subjectEntity.data!!.withIndex()) {
game.sequence = index
}
appendSequenceToSubjectGame(subjectEntity, blockPosition)
itemList.add(itemItemData)
}
return
@ -147,12 +150,22 @@ object LegacyHomeSubjectTransformer {
val itemDataGame = newItemInstance()
itemDataGame.blockPosition = blockPosition + 1
game.sequence = i
game.outerSequence = blockPosition
itemDataGame.game = game
itemList.add(itemDataGame)
addGamePositionAndPackage(game)
}
}
private fun appendSequenceToSubjectGame(subject: SubjectEntity, outerPosition: Int) {
subject.data?.let {
for ((index, game) in it.withIndex()) {
game.sequence = index
game.outerSequence = outerPosition
}
}
}
/**
* 获取填充间距的空白 item
*/

View File

@ -63,7 +63,7 @@ class HomeSlideListAdapter(context: Context,
var exposureEvent: ExposureEvent? = null
if (homeSlide.linkType == "game") {
exposureEvent = ExposureEvent.createEvent(
gameEntity = homeSlide.linkGame,
gameEntity = homeSlide.linkGame?.apply { sequence = actualPosition },
source = listOf(basicExposureSource, ExposureSource("轮播图", "")))
itemData.exposureEventList?.add(exposureEvent)
}

View File

@ -22,9 +22,10 @@ class HomeSlideListViewHolder(val binding: HomeSlideListBinding) : BaseRecyclerV
val context = binding.recyclerView.context
var adapter = binding.recyclerView.adapter
itemData.exposureEventList = arrayListOf()
itemData.exposureEventList = itemData.exposureEventList ?: arrayListOf()
if (adapter is HomeSlideListAdapter) {
adapter.itemData = itemData
adapter.checkResetData(slideList)
// 刷新页面时有可能动画会出现混乱

View File

@ -1,6 +1,5 @@
package com.gh.gamecenter.search
import android.graphics.Color
import android.os.Bundle
import android.text.TextUtils
import android.view.Gravity
@ -77,8 +76,10 @@ open class SearchDefaultFragment : BaseFragment<Any>() {
})
mHotSearchList = Config.getSettings()?.search?.hotSearch?.apply {
for (hotSearch in this) {
hotSearch.exposureEvent = ExposureEvent.createEvent(hotSearch.toGameEntity(), listOf(ExposureSource("首页搜索"), ExposureSource("热门搜索")))
for ((index, hotSearch) in this.withIndex()) {
hotSearch.exposureEvent = ExposureEvent.createEvent(
hotSearch.toGameEntity().apply { sequence = index },
listOf(ExposureSource("首页搜索"), ExposureSource("热门搜索")))
if (!hotSearch.name.endsWith(hotSearch.nameSuffix ?: "")) {
hotSearch.name = hotSearch.name.removeSuffix(".") + (hotSearch.nameSuffix ?: "")
}

View File

@ -73,7 +73,6 @@ public class GameServersContentAdapter extends BaseRecyclerAdapter implements IE
private boolean mIsNetworkError;
private boolean mIsLoaded;
private static final int VIEW_TYPE_TOP = 0;
private static final int VIEW_TYPE_ITEM = 1;
private static final int VIEW_TYPE_FOOTER = 2;
@ -105,7 +104,6 @@ public class GameServersContentAdapter extends BaseRecyclerAdapter implements IE
addList();
}
public void addList() {
mIsLoaded = false;
notifyItemChanged(getItemCount() - 1);
@ -119,9 +117,11 @@ public class GameServersContentAdapter extends BaseRecyclerAdapter implements IE
.subscribe(new Response<List<GameEntity>>() {
@Override
public void onResponse(List<GameEntity> response) {
int realIndex = 0;
for (int i = 0; i < response.size(); i++) {
// 初始化游戏状态
GameEntity entity = response.get(i);
entity.setSequence(mPage * realIndex++);
entity.setEntryMap(DownloadManager.getInstance(mContext).getEntryMap(entity.getName()));
ApkActiveUtils.filterHideApk(entity); // 过滤隐藏apk
@ -294,7 +294,17 @@ public class GameServersContentAdapter extends BaseRecyclerAdapter implements IE
ArrayList<ExposureSource> exposureSources = new ArrayList<>();
exposureSources.add(new ExposureSource("开服表", ""));
exposureSources.add(new ExposureSource(mType, fixedTop));
String exposureSourceValue = getExposureSourceValue();
String displayType;
if ("开服".equals(mType)) {
displayType = "开服";
} else {
displayType = "开测";
}
exposureSources.add(new ExposureSource(displayType, exposureSourceValue));
ExposureEvent exposureEvent = ExposureEvent.Companion.createEvent(gameEntity,
exposureSources,
null,
@ -351,6 +361,51 @@ public class GameServersContentAdapter extends BaseRecyclerAdapter implements IE
return mEntityList.size() + 1;
}
private String getExposureSourceValue() {
StringBuilder sb = new StringBuilder();
if ("开服".equals(mType)) {
if ("today".equals(mDay)) {
sb.append("今日");
sb.append(mType);
} else if ("after".equals(mDay)) {
sb.append("后续");
sb.append(mType);
} else if ("tomorrow".equals(mDay)) {
sb.append("明日");
sb.append(mType);
} else {
sb.append("全部");
sb.append(mType);
}
if (mHour != null) {
sb.append(mHour);
sb.append("");
}
if (mTag != null) {
sb.append("+");
sb.append(mTag.replace("-", "+"));
}
} else {
if ("today".equals(mDay)) {
sb.append("今日开测");
} else if ("after".equals(mDay)) {
sb.append("后续开测");
sb.append(mType);
} else if ("tomorrow".equals(mDay)) {
sb.append("明日开测");
} else {
sb.append("全部开测");
}
sb.append("+");
if ("开测".equals(mType)) {
sb.append("全部");
} else {
sb.append(mType);
}
}
return sb.toString();
}
void initGameTestViewHolder(final GameEntity gameEntity, final GameTestViewHolder viewHolder) {
viewHolder.gameName.setText(gameEntity.getName());
BindingAdapters.setGame(viewHolder.gameThumb, gameEntity);

View File

@ -86,7 +86,7 @@ class TagsListAdapter(context: Context,
val padTop = if (position == 0) 16F.dip2px() else 8F.dip2px()
holder.itemView.setPadding(16F.dip2px(), padTop, 16F.dip2px(), 8F.dip2px())
gameEntity.sequence = position + 1
gameEntity.sequence = position
val exposureSource = ExposureSource("标签详情", "${mViewModel.selectedTag.name} + ${mViewModel.getSortTypeInChinese()}")
val exposureSourceList = arrayListOf<ExposureSource>()