fix:CPM微信小游戏功能优化—客户端 https://jira.shanqu.cc/browse/GHZSCY-8069
This commit is contained in:
@ -3,12 +3,7 @@ package com.gh.gamecenter.home.custom
|
||||
import android.annotation.SuppressLint
|
||||
import android.app.Application
|
||||
import androidx.collection.ArrayMap
|
||||
import androidx.lifecycle.AndroidViewModel
|
||||
import androidx.lifecycle.LiveData
|
||||
import androidx.lifecycle.MediatorLiveData
|
||||
import androidx.lifecycle.MutableLiveData
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.ViewModelProvider
|
||||
import androidx.lifecycle.*
|
||||
import com.gh.common.util.GameUtils
|
||||
import com.gh.common.util.NewFlatLogUtils
|
||||
import com.gh.common.util.NewLogUtils
|
||||
@ -33,24 +28,10 @@ import com.gh.gamecenter.feature.exposure.ExposureEvent
|
||||
import com.gh.gamecenter.home.PageConfigure
|
||||
import com.gh.gamecenter.home.custom.GamePositionAndPackageHelper.Companion.putGameWithPosition
|
||||
import com.gh.gamecenter.home.custom.eventlistener.OnCustomPageEventListener
|
||||
import com.gh.gamecenter.home.custom.model.CustomCommonContentCollectionItem
|
||||
import com.gh.gamecenter.home.custom.model.CustomDspPlaceholderItem
|
||||
import com.gh.gamecenter.home.custom.model.CustomPKItem
|
||||
import com.gh.gamecenter.home.custom.model.CustomPageData
|
||||
import com.gh.gamecenter.home.custom.model.CustomPageItem
|
||||
import com.gh.gamecenter.home.custom.model.*
|
||||
import com.gh.gamecenter.home.custom.model.CustomPageItem.Companion.COMPONENTS_COLLECTION_STYLE_REFRESH_ICONS_4_2
|
||||
import com.gh.gamecenter.home.custom.model.CustomPageItem.Companion.COMPONENTS_COLLECTION_STYLE_REFRESH_SLIDE_LIST
|
||||
import com.gh.gamecenter.home.custom.model.CustomPageRepository
|
||||
import com.gh.gamecenter.home.custom.model.CustomPluginItem
|
||||
import com.gh.gamecenter.home.custom.model.CustomRecentGamesItem
|
||||
import com.gh.gamecenter.home.custom.model.CustomSplitCommonContentCollectionItem
|
||||
import com.gh.gamecenter.home.custom.model.CustomSplitSubjectItem
|
||||
import com.gh.gamecenter.home.custom.model.CustomSubjectCollectionItem
|
||||
import com.gh.gamecenter.home.custom.model.CustomSubjectItem
|
||||
import com.gh.gamecenter.home.custom.model.CustomWeChatMiniGamesCPMSubjectItem
|
||||
import com.gh.gamecenter.livedata.Event
|
||||
import com.gh.gamecenter.login.user.UserRepository
|
||||
import com.gh.gamecenter.login.user.UserViewModel
|
||||
import com.gh.gamecenter.wrapper.SearchToolbarTabWrapperViewModel
|
||||
import com.lightgame.utils.Utils
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
@ -117,11 +98,6 @@ class CustomPageViewModel(application: Application) : AndroidViewModel(applicati
|
||||
|
||||
private val subjectChangedMap: ArrayMap<SubjectChanged, List<GameEntity>> = ArrayMap()
|
||||
|
||||
/**
|
||||
* 微信CPM专题当前的页码记录
|
||||
*/
|
||||
private val cpmSubjectChangedPageMap: ArrayMap<String, Int> = ArrayMap()
|
||||
|
||||
private lateinit var _pageTracker: CustomPageTracker
|
||||
|
||||
val pageTracker: CustomPageTracker
|
||||
@ -134,6 +110,9 @@ class CustomPageViewModel(application: Application) : AndroidViewModel(applicati
|
||||
|
||||
var shouldScrollToTop: Boolean = false
|
||||
|
||||
private var loadFirstDisposable: Disposable? = null
|
||||
private var loadMoreDisposable: Disposable? = null
|
||||
|
||||
fun init(
|
||||
pageConfigure: PageConfigure,
|
||||
searchToolbarTabWrapperViewModel: SearchToolbarTabWrapperViewModel?,
|
||||
@ -208,7 +187,15 @@ class CustomPageViewModel(application: Application) : AndroidViewModel(applicati
|
||||
|
||||
fun loadFirst(isPullToRefresh: Boolean, forceLoad: Boolean = false) {
|
||||
_loadStatus.value = LoadStatus.INIT_LOADING to isPullToRefresh
|
||||
repository.loadFirstCustomPageData(pageConfigure.pageId, forceLoad)
|
||||
|
||||
if (loadFirstDisposable != null && !loadFirstDisposable!!.isDisposed) {
|
||||
// 有可能上一次刷新数据还未获取成功,又再次触发了下拉刷新
|
||||
loadFirstDisposable?.dispose()
|
||||
}
|
||||
if (loadMoreDisposable != null && !loadMoreDisposable!!.isDisposed) {
|
||||
loadMoreDisposable?.dispose()
|
||||
}
|
||||
loadFirstDisposable = repository.loadFirstCustomPageData(pageConfigure.pageId, forceLoad)
|
||||
.map { (custom, list) ->
|
||||
Triple(custom, list, getPositionAndPackageMap(list))
|
||||
}
|
||||
@ -255,7 +242,7 @@ class CustomPageViewModel(application: Application) : AndroidViewModel(applicati
|
||||
|
||||
}
|
||||
|
||||
}).addDisposable()
|
||||
})
|
||||
|
||||
}
|
||||
|
||||
@ -273,7 +260,7 @@ class CustomPageViewModel(application: Application) : AndroidViewModel(applicati
|
||||
}
|
||||
if (repository.isLoadingPKData) return
|
||||
_loadStatus.value = LoadStatus.LIST_LOADING to false
|
||||
repository.loadNextCustomPageData(pageConfigure.pageId)
|
||||
loadMoreDisposable = repository.loadNextCustomPageData(pageConfigure.pageId)
|
||||
.map {
|
||||
it to getPositionAndPackageMap(it)
|
||||
}
|
||||
@ -298,7 +285,7 @@ class CustomPageViewModel(application: Application) : AndroidViewModel(applicati
|
||||
super.onFailure(exception)
|
||||
_loadStatus.value = LoadStatus.LIST_FAILED to false
|
||||
}
|
||||
}).addDisposable()
|
||||
})
|
||||
}
|
||||
|
||||
override fun onRetry() {
|
||||
@ -388,59 +375,7 @@ class CustomPageViewModel(application: Application) : AndroidViewModel(applicati
|
||||
}
|
||||
|
||||
override fun onChangeABatch(subjectEntity: SubjectEntity) =
|
||||
if (subjectEntity.isWechatColumnCPM) {
|
||||
onChangeWGameCPMABatch(subjectEntity)
|
||||
} else {
|
||||
onChangeNormalGameABatch(subjectEntity)
|
||||
}
|
||||
|
||||
/**
|
||||
* 微信小游戏CPM的“换一批”功能实现
|
||||
*
|
||||
* @see <a href="https://jira.shanqu.cc/browse/GHZSCY-7167">【光环助手】CPM微信小游戏“换一批”功能优化</a>
|
||||
*/
|
||||
private fun onChangeWGameCPMABatch(subjectEntity: SubjectEntity) {
|
||||
val subjectId = subjectEntity.id ?: return
|
||||
val page = cpmSubjectChangedPageMap[subjectId] ?: let {
|
||||
// 第一次点击“换一批”时,先缓存第一页的数据
|
||||
subjectChangedMap[SubjectChanged(subjectId, 1)] = subjectEntity.data
|
||||
2
|
||||
}
|
||||
val subjectChanged = SubjectChanged(subjectId, page)
|
||||
val gameList = subjectChangedMap[subjectChanged]
|
||||
if (gameList != null) {// 直接读取缓存数据
|
||||
notifyWGameCPMABatchChanged(gameList, subjectId, page)
|
||||
} else {
|
||||
repository.loadChangeSubjectWGameCPM(page, subjectEntity.size.limit, subjectEntity.onlyFee)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
.subscribe(object : Response<List<GameEntity>>() {
|
||||
override fun onResponse(response: List<GameEntity>?) {
|
||||
if (response != null) {
|
||||
subjectChangedMap[subjectChanged] = response
|
||||
notifyWGameCPMABatchChanged(response, subjectId, page)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onFailure(e: HttpException?) {
|
||||
Utils.toast(getApplication(), "网络异常")
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
private fun notifyWGameCPMABatchChanged(gameList: List<GameEntity>, subjectId: String, page: Int) {
|
||||
val nextPage: Int
|
||||
val cpmGameList = if (gameList.isEmpty()) {
|
||||
nextPage = 1// 已经到最后一页了,下一页是第一页
|
||||
subjectChangedMap[SubjectChanged(subjectId, 1)]!!
|
||||
} else {
|
||||
nextPage = page + 1
|
||||
gameList
|
||||
}
|
||||
cpmSubjectChangedPageMap[subjectId] = nextPage// 加载下一页数据
|
||||
changeSubjectCustomPageItem(subjectId, ArrayList(cpmGameList))
|
||||
}
|
||||
onChangeNormalGameABatch(subjectEntity)
|
||||
|
||||
/**
|
||||
* 光环游戏的“换一批”功能实现
|
||||
@ -564,40 +499,90 @@ class CustomPageViewModel(application: Application) : AndroidViewModel(applicati
|
||||
/**
|
||||
* 通过CPM接口异步请求获取的微信小游戏数据插入
|
||||
*/
|
||||
private fun notifyWechatMiniGameCPMSubjectItemChanged(result: Pair<String, List<GameEntity>>) {
|
||||
private fun notifyWechatMiniGameCPMSubjectItemChanged(result: Pair<Int, List<GameEntity>>) {
|
||||
|
||||
val (componentPosition, gameList) = result
|
||||
val oldData = _dataList.value ?: return
|
||||
val index = oldData.indexOfFirst {
|
||||
it is CustomWeChatMiniGamesCPMSubjectItem && it.data.id == result.first
|
||||
}
|
||||
if (index == -1) return
|
||||
val subjectItem = (oldData[index] as CustomWeChatMiniGamesCPMSubjectItem).apply {
|
||||
data.data = result.second.toMutableList()
|
||||
data.isWechatColumnCPM = true
|
||||
}
|
||||
val position = subjectItem.position
|
||||
val componentPosition = subjectItem.componentPosition
|
||||
val newData = oldData.toMutableList()
|
||||
val customPageItemList = repository.convertColumnDetailSubjectItems(
|
||||
position,
|
||||
componentPosition,
|
||||
subjectItem.link,
|
||||
subjectItem.data
|
||||
)
|
||||
if (customPageItemList.isEmpty()) return
|
||||
|
||||
if (index == 0) {
|
||||
shouldScrollToTop = true
|
||||
// 是否是cpm第一页数据
|
||||
val itemPosition = oldData.indexOfFirst { it.componentPosition == componentPosition }
|
||||
val targetItem = oldData.getOrNull(itemPosition)
|
||||
when {
|
||||
targetItem is CustomWeChatMiniGamesCPMSubjectItem -> {
|
||||
// 第一次添加数据
|
||||
val subject = targetItem.data
|
||||
subject.data = gameList.toMutableList()
|
||||
subject.isWechatColumnCPM = true
|
||||
|
||||
val cpmSubjectItemList = repository.convertColumnDetailSubjectItems(
|
||||
targetItem.position,
|
||||
componentPosition,
|
||||
targetItem.link,
|
||||
subject
|
||||
)
|
||||
if (cpmSubjectItemList.isEmpty()) return
|
||||
|
||||
if (itemPosition == 0) {
|
||||
shouldScrollToTop = true
|
||||
}
|
||||
|
||||
val newData = oldData.toMutableList()
|
||||
newData[itemPosition] = cpmSubjectItemList[0]
|
||||
newData.addAll(itemPosition + 1, cpmSubjectItemList.subList(1, cpmSubjectItemList.size))
|
||||
newData.forEachIndexed { pos, customPageItem ->
|
||||
customPageItem.position = pos
|
||||
}
|
||||
repository.notifyPositionChanged(newData.size)
|
||||
gamePositionAndPackageHelper.clear()
|
||||
gamePositionAndPackageHelper.putAll(getPositionAndPackageMap(newData))
|
||||
_dataList.value = newData
|
||||
}
|
||||
|
||||
targetItem is CustomSplitSubjectItem -> {// 添加后续的数据
|
||||
val subject = targetItem.data
|
||||
subject.data = gameList.toMutableList()
|
||||
subject.isWechatColumnCPM = true
|
||||
|
||||
val cpmSubjectItemList = repository.convertColumnDetailSubjectItems(
|
||||
targetItem.position,
|
||||
componentPosition,
|
||||
targetItem.link,
|
||||
subject
|
||||
)
|
||||
if (cpmSubjectItemList.isEmpty()) return
|
||||
val newData = oldData.toMutableList()
|
||||
val position = newData.indexOfLast { it.componentPosition == componentPosition }
|
||||
newData.addAll(position + 1, cpmSubjectItemList)
|
||||
newData.forEachIndexed { pos, customPageItem ->
|
||||
customPageItem.position = pos
|
||||
}
|
||||
repository.notifyPositionChanged(newData.size)
|
||||
gamePositionAndPackageHelper.clear()
|
||||
gamePositionAndPackageHelper.putAll(getPositionAndPackageMap(newData))
|
||||
_dataList.value = newData
|
||||
}
|
||||
|
||||
targetItem is CustomSubjectItem -> {
|
||||
val subject = targetItem.data.copy()
|
||||
val originalGameList = subject.data ?: mutableListOf()
|
||||
subject.data = (originalGameList + gameList).toMutableList()
|
||||
subject.isWechatColumnCPM = true
|
||||
val cpmSubjectItemList = repository.convertColumnDetailSubjectItems(
|
||||
targetItem.position,
|
||||
componentPosition,
|
||||
targetItem.link,
|
||||
subject
|
||||
)
|
||||
if (cpmSubjectItemList.isEmpty()) return
|
||||
|
||||
val newData = oldData.toMutableList()
|
||||
newData[itemPosition] = cpmSubjectItemList.first()
|
||||
gamePositionAndPackageHelper.clear()
|
||||
gamePositionAndPackageHelper.putAll(getPositionAndPackageMap(newData))
|
||||
_dataList.value = newData
|
||||
}
|
||||
}
|
||||
|
||||
newData[index] = customPageItemList[0]
|
||||
newData.addAll(index + 1, customPageItemList.subList(1, customPageItemList.size))
|
||||
newData.forEachIndexed { pos, customPageItem ->
|
||||
customPageItem.position = pos
|
||||
}
|
||||
repository.notifyPositionChanged(newData.size)
|
||||
gamePositionAndPackageHelper.clear()
|
||||
gamePositionAndPackageHelper.putAll(getPositionAndPackageMap(newData))
|
||||
_dataList.value = newData
|
||||
}
|
||||
|
||||
/**
|
||||
@ -926,6 +911,12 @@ class CustomPageViewModel(application: Application) : AndroidViewModel(applicati
|
||||
|
||||
override fun onCleared() {
|
||||
super.onCleared()
|
||||
if (loadFirstDisposable != null && !loadFirstDisposable!!.isDisposed) {
|
||||
loadFirstDisposable?.dispose()
|
||||
}
|
||||
if (loadMoreDisposable != null && !loadMoreDisposable!!.isDisposed) {
|
||||
loadMoreDisposable?.dispose()
|
||||
}
|
||||
compositeDisposable.clear()
|
||||
repository.onClear()
|
||||
}
|
||||
@ -952,8 +943,7 @@ class CustomPageViewModel(application: Application) : AndroidViewModel(applicati
|
||||
|
||||
}
|
||||
|
||||
class Factory(private val mApplication: Application)
|
||||
: ViewModelProvider.NewInstanceFactory() {
|
||||
class Factory(private val mApplication: Application) : ViewModelProvider.NewInstanceFactory() {
|
||||
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
return CustomPageViewModel(mApplication) as T
|
||||
|
||||
@ -159,7 +159,7 @@ class CustomPageRepository private constructor(
|
||||
}
|
||||
}
|
||||
|
||||
val wechatMiniGameCPMItemLiveData: LiveData<Pair<String, List<GameEntity>>> =
|
||||
val wechatMiniGameCPMItemLiveData: LiveData<Pair<Int, List<GameEntity>>> =
|
||||
wGameSubjectCPMListUseCase.wechatMiniGameCPMListLiveData
|
||||
|
||||
val hiddenNotifications: LiveData<HashMap<String, MutableSet<String>>>
|
||||
@ -257,7 +257,8 @@ class CustomPageRepository private constructor(
|
||||
gameChildPosition = 0
|
||||
displayingGameIdSet.clear()
|
||||
isLoadingPKData = false
|
||||
return remoteDataSource.loadCustomPageData(pageId, pageInfo.page, forceLoad)
|
||||
wGameSubjectCPMListUseCase.clear()
|
||||
return remoteDataSource.loadCustomPageData(pageId, 1, forceLoad)
|
||||
.map {
|
||||
it to transformRawDataIntoItemData(it, forceLoad)
|
||||
}
|
||||
@ -367,7 +368,12 @@ class CustomPageRepository private constructor(
|
||||
pageInfo.componentPosition
|
||||
)
|
||||
)
|
||||
wGameSubjectCPMListUseCase.getWechatMiniGameCPMList(subject.id, subject.size.limit, subject.onlyFee)
|
||||
wGameSubjectCPMListUseCase.getWechatMiniGameCPMList(
|
||||
pageInfo.componentPosition,
|
||||
subject.onlyFee,
|
||||
subject.size.index,
|
||||
subject.size.limit,
|
||||
)
|
||||
pageInfo.positionIncrement()
|
||||
pageInfo.componentPositionIncrement()
|
||||
}
|
||||
@ -903,12 +909,6 @@ class CustomPageRepository private constructor(
|
||||
.map(RegionSettingHelper.filterGame)
|
||||
.map(ApkActiveUtils.filterMapperList)
|
||||
|
||||
fun loadChangeSubjectWGameCPM(page: Int, minimumSize: Int, onlyFee: Boolean): Observable<MutableList<GameEntity>> =
|
||||
wGameSubjectCPMRemoteDataSource.getEditorRecommendCPMList(page = page, minimumSize = minimumSize, onlyFee = onlyFee)// 微信小游戏CPM专题的“换一批”接口
|
||||
.toObservable()
|
||||
.map(RegionSettingHelper.filterGame)
|
||||
.map(ApkActiveUtils.filterMapperList)
|
||||
|
||||
fun loadSlideDiscoverCardGames(): Observable<List<GameEntity>> =
|
||||
remoteDataSource.loadSlideDiscoverCardGames()
|
||||
.map(RegionSettingHelper.filterGame)
|
||||
@ -1013,6 +1013,7 @@ class CustomPageRepository private constructor(
|
||||
}
|
||||
|
||||
fun onClear() {
|
||||
wGameSubjectCPMListUseCase.clear()
|
||||
compositeDisposable.clear()
|
||||
}
|
||||
|
||||
|
||||
@ -19,7 +19,6 @@ class QGameSubjectListRepository(
|
||||
order: String?,
|
||||
ad: String?,
|
||||
columnCollectionId: String?,
|
||||
minimumSize: Int,
|
||||
onlyFee: Boolean,
|
||||
): Single<MutableList<GameEntity>> {
|
||||
return api.getQGameColumn(column_id, order, page, 20)
|
||||
|
||||
@ -17,10 +17,9 @@ class WGameSubjectCPMListRepository(
|
||||
order: String?,
|
||||
ad: String?,
|
||||
columnCollectionId: String?,
|
||||
minimumSize: Int,
|
||||
onlyFee: Boolean
|
||||
): Single<MutableList<GameEntity>> {
|
||||
return dataSource.getEditorRecommendCPMList(page = page, minimumSize = minimumSize, onlyFee = onlyFee)
|
||||
return dataSource.getEditorRecommendCPMList(page = page, onlyFee = onlyFee)
|
||||
}
|
||||
|
||||
override fun getColumnSettings(column_id: String?): Observable<SubjectSettingEntity> {
|
||||
|
||||
@ -1,12 +1,11 @@
|
||||
package com.gh.gamecenter.minigame.wechat
|
||||
|
||||
import android.annotation.SuppressLint
|
||||
import androidx.lifecycle.LiveData
|
||||
import com.gh.gamecenter.common.livedata.NonStickyMutableLiveData
|
||||
import com.gh.gamecenter.common.retrofit.BiResponse
|
||||
import com.gh.gamecenter.common.utils.singleToMain
|
||||
import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
import io.reactivex.schedulers.Schedulers
|
||||
import io.reactivex.disposables.CompositeDisposable
|
||||
|
||||
/**
|
||||
* 微信小游戏CPM-网域层
|
||||
@ -15,32 +14,87 @@ class WGameSubjectCPMListUseCase(
|
||||
private val repository: WGameSubjectCPMListRepository = WGameSubjectCPMListRepository()
|
||||
) {
|
||||
|
||||
/**
|
||||
* 微信专题CPM请求记录,用于避免重复请求,以专题ID作为Key
|
||||
*/
|
||||
private val requestKeyList = mutableListOf<String>()
|
||||
private val compositeDisposable = CompositeDisposable()
|
||||
|
||||
/**
|
||||
* 微信小游戏CPM列表,这里的LiveData充当类似于EventBus的角色,因此使用NonStickyMutableLiveData
|
||||
*/
|
||||
private val _wechatMiniGameCPMListLiveData = NonStickyMutableLiveData<Pair<String, List<GameEntity>>>()
|
||||
val wechatMiniGameCPMListLiveData: LiveData<Pair<String, List<GameEntity>>> = _wechatMiniGameCPMListLiveData
|
||||
private val _wechatMiniGameCPMListLiveData = NonStickyMutableLiveData<Pair<Int, List<GameEntity>>>()
|
||||
val wechatMiniGameCPMListLiveData: LiveData<Pair<Int, List<GameEntity>>> = _wechatMiniGameCPMListLiveData
|
||||
|
||||
@SuppressLint("CheckResult")
|
||||
fun getWechatMiniGameCPMList(subjectId: String?, minimumSize: Int, onlyFee: Boolean) {
|
||||
if (subjectId.isNullOrEmpty() || requestKeyList.contains(subjectId)) {
|
||||
return
|
||||
}
|
||||
/**
|
||||
* componentPosition:组件位置,记录当前cpm数据需要插入的位置
|
||||
* 由于用户触发下拉刷新,componentPosition位置可能发生变化,所以当出现下拉刷新时,需要取消这里的所有请求
|
||||
*/
|
||||
fun getWechatMiniGameCPMList(componentPosition: Int, onlyFee: Boolean, targetSize: Int, minimumSize: Int) {
|
||||
loadCpmGameList(1, componentPosition, onlyFee, targetSize, minimumSize, 0, 1, listOf())
|
||||
}
|
||||
|
||||
requestKeyList.add(subjectId)
|
||||
repository.getColumn(null, 1, null, null, null, null, minimumSize, onlyFee)
|
||||
.subscribeOn(Schedulers.io())
|
||||
.observeOn(AndroidSchedulers.mainThread())
|
||||
fun loadCpmGameList(
|
||||
page: Int,
|
||||
componentPosition: Int,
|
||||
onlyFee: Boolean,
|
||||
targetSize: Int,
|
||||
minimumSize: Int,
|
||||
currentSize: Int,
|
||||
count: Int,
|
||||
gameList: List<GameEntity>
|
||||
) {
|
||||
repository.getColumn(null, page, null, null, null, null, onlyFee)
|
||||
.compose(singleToMain())
|
||||
.subscribe(object : BiResponse<List<GameEntity>>() {
|
||||
override fun onSuccess(data: List<GameEntity>) {
|
||||
requestKeyList.remove(subjectId)
|
||||
_wechatMiniGameCPMListLiveData.value = subjectId to data
|
||||
val total = currentSize + data.size
|
||||
val needShowGames = gameList + data
|
||||
if (total >= targetSize || count >= MAX_LOAD_COUNT) {
|
||||
// 停止继续加载
|
||||
if (total >= minimumSize && needShowGames.isNotEmpty()) {
|
||||
// 游戏数量不小于最小游戏数量才可以显示
|
||||
_wechatMiniGameCPMListLiveData.value = componentPosition to needShowGames
|
||||
}
|
||||
} else {
|
||||
// 继续加载下一页数据
|
||||
if (total >= minimumSize) {
|
||||
// 游戏数量不小于最小游戏数量才可以显示
|
||||
if (needShowGames.isNotEmpty()) {
|
||||
_wechatMiniGameCPMListLiveData.value = componentPosition to needShowGames
|
||||
}
|
||||
|
||||
loadCpmGameList(
|
||||
page + 1,
|
||||
componentPosition,
|
||||
onlyFee,
|
||||
targetSize,
|
||||
minimumSize,
|
||||
total,
|
||||
count + 1,
|
||||
listOf()
|
||||
)
|
||||
} else {
|
||||
// 游戏数量太少,暂不显示,等后续数据加载出来,达到最小数量限制后一起显示
|
||||
loadCpmGameList(
|
||||
page + 1,
|
||||
componentPosition,
|
||||
onlyFee,
|
||||
targetSize,
|
||||
minimumSize,
|
||||
total,
|
||||
count + 1,
|
||||
needShowGames
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
}).let(compositeDisposable::add)
|
||||
}
|
||||
|
||||
fun clear() {
|
||||
compositeDisposable.clear()
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
private const val MAX_LOAD_COUNT = 6
|
||||
}
|
||||
}
|
||||
@ -17,7 +17,6 @@ class WGameSubjectCPMRemoteDataSource(
|
||||
fun getEditorRecommendCPMList(
|
||||
page: Int,
|
||||
pageSize: Int = 10,
|
||||
minimumSize: Int,
|
||||
onlyFee: Boolean
|
||||
): Single<MutableList<GameEntity>> {
|
||||
val meta = MetaUtil.getMeta()
|
||||
@ -39,38 +38,33 @@ class WGameSubjectCPMRemoteDataSource(
|
||||
return api.getEditorRecommendList(request.toRequestBody())
|
||||
.map {
|
||||
if (it.ret == 0) {
|
||||
// 数量不满足最小值时直接返回空
|
||||
if (onlyFee && minimumSize > 0 && it.appInfoList.size < minimumSize) {
|
||||
mutableListOf()
|
||||
} else {
|
||||
it.appInfoList.map { info ->
|
||||
GameEntity(
|
||||
mName = info.appName,
|
||||
mIcon = info.logo,
|
||||
mBrief = info.briefIntro,
|
||||
miniGameUid = info.appID,
|
||||
miniGameAppId = info.userName,
|
||||
miniGameCategory = Constants.WECHAT_MINI_GAME,
|
||||
profit = Constants.WECHAT_MINI_GAME_PROFIT_CPM,
|
||||
miniGameAppStatus = 2,
|
||||
miniGameAppPath = info.wechatAppPath,
|
||||
miniGameExtData = info.extData,
|
||||
miniGameRecommendId = info.recommendID,
|
||||
mTagStyle = arrayListOf(
|
||||
TagStyleEntity(
|
||||
name = info.categoryName,
|
||||
color = TAG_COLOR,
|
||||
background = TAG_BACKGROUND
|
||||
),
|
||||
TagStyleEntity(
|
||||
name = info.subcategoryName,
|
||||
color = TAG_COLOR,
|
||||
background = TAG_BACKGROUND
|
||||
)
|
||||
it.appInfoList.map { info ->
|
||||
GameEntity(
|
||||
mName = info.appName,
|
||||
mIcon = info.logo,
|
||||
mBrief = info.briefIntro,
|
||||
miniGameUid = info.appID,
|
||||
miniGameAppId = info.userName,
|
||||
miniGameCategory = Constants.WECHAT_MINI_GAME,
|
||||
profit = Constants.WECHAT_MINI_GAME_PROFIT_CPM,
|
||||
miniGameAppStatus = 2,
|
||||
miniGameAppPath = info.wechatAppPath,
|
||||
miniGameExtData = info.extData,
|
||||
miniGameRecommendId = info.recommendID,
|
||||
mTagStyle = arrayListOf(
|
||||
TagStyleEntity(
|
||||
name = info.categoryName,
|
||||
color = TAG_COLOR,
|
||||
background = TAG_BACKGROUND
|
||||
),
|
||||
TagStyleEntity(
|
||||
name = info.subcategoryName,
|
||||
color = TAG_COLOR,
|
||||
background = TAG_BACKGROUND
|
||||
)
|
||||
)
|
||||
}.toMutableList()
|
||||
}
|
||||
)
|
||||
}.toMutableList()
|
||||
} else {
|
||||
mutableListOf()
|
||||
}
|
||||
|
||||
@ -19,7 +19,6 @@ class WGameSubjectListRepository(
|
||||
order: String?,
|
||||
ad: String?,
|
||||
columnCollectionId: String?,
|
||||
minimumSize: Int,
|
||||
onlyFee: Boolean,
|
||||
): Single<MutableList<GameEntity>> {
|
||||
return api.getWGameColumn(column_id, order, page, 20)
|
||||
|
||||
@ -14,7 +14,6 @@ interface ISubjectListRepository {
|
||||
order: String?,
|
||||
ad: String?,
|
||||
columnCollectionId: String?,
|
||||
minimumSize: Int,
|
||||
onlyFee: Boolean
|
||||
): Single<MutableList<GameEntity>>
|
||||
|
||||
|
||||
@ -302,6 +302,14 @@ open class SubjectListFragment : LazyListFragment<GameEntity, SubjectListViewMod
|
||||
}
|
||||
}
|
||||
|
||||
override fun theNumberNeededToFillAScreen(): Int {
|
||||
return if (mListViewModel.subjectData.subjectType == SubjectData.SubjectType.WECHAT_GAME_CPM) 20 else super.theNumberNeededToFillAScreen()
|
||||
}
|
||||
|
||||
override fun autoLoadMore() {
|
||||
mListViewModel.load(LoadType.NORMAL)
|
||||
}
|
||||
|
||||
override fun onDarkModeChanged() {
|
||||
super.onDarkModeChanged()
|
||||
mAdapter?.let { it.notifyItemRangeChanged(0, it.itemCount) }
|
||||
|
||||
@ -18,7 +18,6 @@ class SubjectListRepository(
|
||||
order: String?,
|
||||
ad: String?,
|
||||
columnCollectionId: String?,
|
||||
minimumSize: Int,
|
||||
onlyFee: Boolean,
|
||||
): Single<MutableList<GameEntity>> {
|
||||
return api.getColumn(column_id, sort, order, ad, columnCollectionId, page)
|
||||
|
||||
@ -6,6 +6,7 @@ import androidx.lifecycle.ViewModelProvider
|
||||
import com.gh.common.exposure.ExposureUtils
|
||||
import com.gh.common.util.AdHelper
|
||||
import com.gh.gamecenter.common.baselist.ListViewModel
|
||||
import com.gh.gamecenter.common.baselist.LoadParams
|
||||
import com.gh.gamecenter.common.baselist.LoadStatus
|
||||
import com.gh.gamecenter.common.baselist.LoadType
|
||||
import com.gh.gamecenter.common.exposure.ExposureSource
|
||||
@ -17,7 +18,6 @@ import com.gh.gamecenter.feature.entity.GameEntity
|
||||
import com.gh.gamecenter.feature.entity.PageLocation
|
||||
import com.gh.gamecenter.feature.entity.TagStyleEntity
|
||||
import com.gh.gamecenter.feature.exposure.ExposureConstants
|
||||
import com.gh.gamecenter.retrofit.RetrofitManager
|
||||
import io.reactivex.Observable
|
||||
import io.reactivex.Single
|
||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
||||
@ -38,6 +38,8 @@ open class SubjectListViewModel(
|
||||
|
||||
var lastPageDataMap: HashMap<String, String>? = null
|
||||
|
||||
private var total = 0
|
||||
|
||||
private val repository = SubjectRepositoryFactory.createListRepo(subjectData.subjectType)
|
||||
|
||||
override fun provideDataObservable(page: Int): Observable<List<GameEntity>>? = null
|
||||
@ -50,7 +52,6 @@ open class SubjectListViewModel(
|
||||
subjectData.filter.ifEmpty { "type:全部" },
|
||||
AdHelper.getIdfaString(),
|
||||
columnCollectionId,
|
||||
-1,
|
||||
false
|
||||
)
|
||||
}
|
||||
@ -110,6 +111,7 @@ open class SubjectListViewModel(
|
||||
|
||||
override fun load(loadType: LoadType) {
|
||||
if (loadType == LoadType.REFRESH) {
|
||||
total = 0
|
||||
initLoadParams()
|
||||
} else if (loadType == LoadType.RETRY) {
|
||||
mLoadStatusLiveData.value = LoadStatus.LIST_LOADED
|
||||
@ -122,6 +124,49 @@ open class SubjectListViewModel(
|
||||
}
|
||||
}
|
||||
|
||||
override fun loadStatusControl(size: Int) {
|
||||
if (size > 0) {
|
||||
total += size
|
||||
}
|
||||
if (subjectData.subjectType == SubjectData.SubjectType.WECHAT_GAME_CPM) {
|
||||
|
||||
if (mCurLoadParams.loadOffset == LoadParams.DEFAULT_OFFSET) {
|
||||
// 第一页不管有没有数据,都设置初始化完毕状态(如果游戏数量不够,会触发自动加载下一页)
|
||||
mLoadStatusLiveData.value = LoadStatus.INIT_LOADED
|
||||
} else {
|
||||
when {
|
||||
total >= CPM_MAX_SIZE -> { // 请求游戏个数到达最大显示数量,列表加载完毕
|
||||
mLoadStatusLiveData.value = LoadStatus.LIST_OVER
|
||||
}
|
||||
|
||||
mCurLoadParams.loadOffset >= CPM_MAX_LOAD_COUNT && total > 0 -> { // 请求次数到达最大请求次数,且游戏总量大于0,列表加载完毕
|
||||
mLoadStatusLiveData.value = LoadStatus.LIST_OVER
|
||||
}
|
||||
|
||||
mCurLoadParams.loadOffset >= CPM_MAX_LOAD_COUNT -> { // 请求次数搭配大最大请求次数,且游戏总量为0,说明没有数据
|
||||
mLoadStatusLiveData.value = LoadStatus.INIT_EMPTY
|
||||
}
|
||||
|
||||
else -> {
|
||||
mLoadStatusLiveData.value = LoadStatus.LIST_LOADED
|
||||
// 继续加载下一页数据
|
||||
load(LoadType.NORMAL)
|
||||
}
|
||||
}
|
||||
}
|
||||
mCurLoadParams.loadOffset += 1
|
||||
} else {
|
||||
super.loadStatusControl(size)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val CPM_MAX_LOAD_COUNT = 6
|
||||
private const val CPM_MAX_SIZE = 20
|
||||
private const val AUTO_LOAD_DURATION = 500L
|
||||
}
|
||||
|
||||
class Factory(
|
||||
private val mApplication: Application,
|
||||
private val subjectData: SubjectData,
|
||||
@ -130,7 +175,13 @@ open class SubjectListViewModel(
|
||||
private val columnCollectionId: String? = null
|
||||
) : ViewModelProvider.NewInstanceFactory() {
|
||||
override fun <T : ViewModel> create(modelClass: Class<T>): T {
|
||||
return SubjectListViewModel(mApplication, subjectData, pageLocation, exposureSourceList, columnCollectionId) as T
|
||||
return SubjectListViewModel(
|
||||
mApplication,
|
||||
subjectData,
|
||||
pageLocation,
|
||||
exposureSourceList,
|
||||
columnCollectionId
|
||||
) as T
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -20,7 +20,7 @@ class SubjectViewModel(
|
||||
) : AndroidViewModel(application) {
|
||||
|
||||
val subjectNameLD = MutableLiveData<String>()
|
||||
val subjectSettingLD = MutableLiveData<SubjectSettingEntity>()
|
||||
val subjectSettingLD = MutableLiveData<SubjectSettingEntity?>()
|
||||
|
||||
private val repository =
|
||||
SubjectRepositoryFactory.createRepo(subjectData?.subjectType ?: SubjectData.SubjectType.NORMAL)
|
||||
@ -34,7 +34,7 @@ class SubjectViewModel(
|
||||
if (subjectData?.subjectName.isNullOrEmpty()) {
|
||||
loadSubjectName()
|
||||
} else {
|
||||
subjectNameLD.postValue(subjectData?.subjectName)
|
||||
subjectNameLD.postValue(subjectData?.subjectName ?: "")
|
||||
loadSubjectType()
|
||||
}
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user