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> = 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>() val loadStatusLiveData = MutableLiveData() @SuppressLint("CheckResult") fun load(filter: String = ALL) { mCurrentTypeFilter = filter RetrofitManager.getInstance(HaloApp.getInstance()).api.getGameTestServers(mColumnId, null) .subscribeOn(Schedulers.io()) .subscribe(object : BiResponse() { 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) { locationMap.clear() var list: ArrayList? 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() val subList = arrayListOf() 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 create(modelClass: Class): T { return GameServersTestViewModel(mApplication, mColumnId) as T } } }