Files
assistant-android/app/src/main/java/com/gh/gamecenter/servers/GameServersTestViewModel.kt

241 lines
8.6 KiB
Kotlin

package com.gh.gamecenter.servers
import android.annotation.SuppressLint
import android.app.Application
import android.util.SparseIntArray
import androidx.collection.ArrayMap
import androidx.collection.arrayMapOf
import androidx.lifecycle.AndroidViewModel
import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel
import androidx.lifecycle.ViewModelProvider
import com.gh.common.util.ApkActiveUtils
import com.gh.common.util.TimeUtils
import com.gh.common.util.safelyGetInRelease
import com.gh.gamecenter.entity.GameEntity
import com.gh.gamecenter.entity.ServerTestEntity
import com.gh.gamecenter.retrofit.BiResponse
import com.gh.gamecenter.retrofit.RetrofitManager
import com.halo.assistant.HaloApp
import io.reactivex.schedulers.Schedulers
import java.text.SimpleDateFormat
import java.util.*
import kotlin.math.abs
class GameServersTestViewModel(application: Application, private val mColumnId: String)
: AndroidViewModel(application) {
private var mServerTestEntity: ServerTestEntity? = null
private var mTimePositionSparseArray = SparseIntArray()
val locationMap: ArrayMap<String, ArrayList<Int>> = arrayMapOf()
private var mCurrentTimeFilter = ""
private var mCurrentTypeFilter = ""
var testTitle = ""
// dayList 的排序很重要,改前要小心
var dayList = arrayListOf("过去7天", "昨天", "今天", "明天", "后续")
var typeList = arrayListOf(ALL, OPEN_TEST, UNLIMITED_TEST, LIMITED_TEST)
val listLiveData = MutableLiveData<ArrayList<ItemData>>()
val loadStatusLiveData = MutableLiveData<Boolean>()
@SuppressLint("CheckResult")
fun load(filter: String = ALL) {
mCurrentTypeFilter = filter
RetrofitManager.getInstance(HaloApp.getInstance()).api.getGameTestServers(mColumnId, null)
.subscribeOn(Schedulers.io())
.subscribe(object : BiResponse<ServerTestEntity>() {
override fun onSuccess(data: ServerTestEntity) {
mServerTestEntity = data
dayList[0] = "过去${data.settings.testTimeRange}"
transformData(data, filter)
loadStatusLiveData.postValue(true)
}
override fun onFailure(exception: Exception) {
super.onFailure(exception)
loadStatusLiveData.postValue(false)
}
})
}
fun updateTypeFilter(filter: String) {
if (mServerTestEntity != null) {
transformData(mServerTestEntity!!, filter)
} else {
load(filter)
}
mCurrentTypeFilter = filter
}
fun updateTimeFilter(filter: String) {
mCurrentTimeFilter = filter
}
fun getTestEntity(): ServerTestEntity? {
return mServerTestEntity
}
fun getCurrentTypeFilter(): String {
return mCurrentTypeFilter
}
fun getCurrentTimeFilter(): String {
return if (mCurrentTimeFilter.isEmpty()) dayList.first() else mCurrentTimeFilter
}
fun getDayPositionByDayString(day: String): Int {
for ((index, dayString) in dayList.withIndex()) {
if (dayString == day) {
when (index) {
0 -> return mTimePositionSparseArray.get(Day.PAST_DAY.value)
1 -> return mTimePositionSparseArray.get(Day.YESTERDAY.value)
2 -> return mTimePositionSparseArray.get(Day.TODAY.value)
3 -> return mTimePositionSparseArray.get(Day.TOMORROW.value)
4 -> return mTimePositionSparseArray.get(Day.UPCOMING_DAY.value)
}
}
}
return -1
}
fun getDayRangeByPosition(firstVisiblePosition: Int): String {
return when (listLiveData.value?.safelyGetInRelease(firstVisiblePosition)?.readableDaysOffset) {
Day.PAST_DAY.value -> return dayList[0]
Day.YESTERDAY.value -> return dayList[1]
Day.TODAY.value -> return dayList[2]
Day.TOMORROW.value -> return dayList[3]
Day.UPCOMING_DAY.value -> return dayList[4]
else -> ""
}
}
private fun initLocationMap(itemList: ArrayList<ItemData>) {
locationMap.clear()
var list: ArrayList<Int>?
var i = 0
val size: Int = itemList.size
while (i < size) {
itemList[i].game?.let { gameEntity ->
if (gameEntity.getApk().size != 0) {
for ((packageName) in gameEntity.getApk()) {
list = locationMap[packageName]
if (list == null) {
list = ArrayList()
locationMap[packageName] = list
}
list?.add(i)
}
}
}
i++
}
}
private fun transformData(serverTestEntity: ServerTestEntity, filter: String) {
val list = arrayListOf<ItemData>()
val subList = arrayListOf<ItemData>()
mTimePositionSparseArray.clear()
var isEmptyIndeed = true // 列表是否不含有任何一个游戏,这时隐藏所有
for (slice in serverTestEntity.sliceData) {
subList.clear()
val daysOffset = TimeUtils.getDaysOffset(slice.testTime)
var testTimeInHumanReadableFormat: String
if (daysOffset in -1..1) {
testTimeInHumanReadableFormat = when (daysOffset) {
-1 -> "昨天"
0 -> "今天"
else -> "明天"
}
val sdf = SimpleDateFormat("(EEEE)", Locale.CHINA)
testTimeInHumanReadableFormat = testTimeInHumanReadableFormat + " " + sdf.format(slice.testTime * 1000)
} else {
val sdf = SimpleDateFormat("yyyy-MM-dd (EEEE)", Locale.CHINA)
testTimeInHumanReadableFormat = sdf.format(slice.testTime * 1000)
}
val readableDaysOffset = when {
daysOffset < Day.YESTERDAY.value -> Day.PAST_DAY.value
daysOffset > Day.TOMORROW.value -> Day.UPCOMING_DAY.value
else -> daysOffset
}
subList.add(ItemData(time = testTimeInHumanReadableFormat, readableDaysOffset = readableDaysOffset))
for ((index, game) in slice.gameList.withIndex()) {
game.serverType = game.test?.type ?: game.serverType
if (filter == ALL || game.serverType == filter) {
ApkActiveUtils.filterHideApk(game) // 过滤隐藏apk
if (game.test?.gameTag == "type_tag") {
game.test = null
}
game.sequence = index
game.testTime = testTimeInHumanReadableFormat
subList.add(ItemData(game = game, readableDaysOffset = readableDaysOffset))
isEmptyIndeed = false
}
}
// 过滤除昨天今天明天以外没有游戏的子列表
if (subList.size > 1 || abs(daysOffset) <= 1) {
val isCurrentDaysOffsetExist = mTimePositionSparseArray.get(readableDaysOffset, 999) != 999
if (!isCurrentDaysOffsetExist) {
mTimePositionSparseArray.put(readableDaysOffset, list.size)
}
list.addAll(subList)
if (subList.size == 1) {
list.add(ItemData(text = "暂无开测游戏", readableDaysOffset = daysOffset))
}
}
}
if (isEmptyIndeed) {
// 没有游戏的列表不显示日期
list.clear()
}
initLocationMap(list)
listLiveData.postValue(list)
}
companion object {
const val ALL = "全部"
const val OPEN_TEST = "公测"
const val UNLIMITED_TEST = "不删档内测"
const val LIMITED_TEST = "删档内测"
}
enum class Day(val value: Int) {
PAST_DAY(-2),
YESTERDAY(-1),
TODAY(0),
TOMORROW(1),
UPCOMING_DAY(2)
}
class ItemData(var time: String? = null,
var game: GameEntity? = null,
var text: String? = null,
var readableDaysOffset: Int = 0)
class Factory(private val mApplication: Application, private val mColumnId: String) : ViewModelProvider.NewInstanceFactory() {
override fun <T : ViewModel?> create(modelClass: Class<T>): T {
return GameServersTestViewModel(mApplication, mColumnId) as T
}
}
}