diff --git a/manager/app/src/main/java/com/rifsxd/ksunext/ui/viewmodel/ModuleViewModel.kt b/manager/app/src/main/java/com/rifsxd/ksunext/ui/viewmodel/ModuleViewModel.kt index 314e5038..69221aef 100644 --- a/manager/app/src/main/java/com/rifsxd/ksunext/ui/viewmodel/ModuleViewModel.kt +++ b/manager/app/src/main/java/com/rifsxd/ksunext/ui/viewmodel/ModuleViewModel.kt @@ -10,8 +10,13 @@ import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import com.dergoogler.mmrl.platform.model.ModuleConfig import com.dergoogler.mmrl.platform.model.ModuleConfig.Companion.asModuleConfig +import com.dergoogler.mmrl.platform.Platform +import com.dergoogler.mmrl.platform.TIMEOUT_MILLIS +import kotlinx.coroutines.delay import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch +import kotlinx.coroutines.withContext +import kotlinx.coroutines.withTimeoutOrNull import java.text.Collator import java.util.Locale import com.rifsxd.ksunext.ksuApp @@ -88,58 +93,71 @@ class ModuleViewModel : ViewModel() { } fun fetchModuleList() { - viewModelScope.launch(Dispatchers.IO) { - isRefreshing = true + + viewModelScope.launch { - val oldModuleList = modules - - val start = SystemClock.elapsedRealtime() - - kotlin.runCatching { - isOverlayAvailable = overlayFsAvailable() - - val result = listModules() - - Log.i(TAG, "result: $result") - - val array = JSONArray(result) - modules = (0 until array.length()) - .asSequence() - .map { array.getJSONObject(it) } - .map { obj -> - val id = obj.getString("id") - val config = id.asModuleConfig - - ModuleInfo( - id, - config.name ?: obj.optString("name"), - obj.optString("author", "Unknown"), - obj.optString("version", "Unknown"), - obj.optInt("versionCode", 0), - config.description ?: obj.optString("description"), - obj.getBoolean("enabled"), - obj.getBoolean("update"), - obj.getBoolean("remove"), - obj.optString("updateJson"), - obj.optBoolean("web"), - obj.optBoolean("action"), - obj.getString("dir_id"), - config - ) - }.toList() - isNeedRefresh = false - }.onFailure { e -> - Log.e(TAG, "fetchModuleList: ", e) - isRefreshing = false + withContext(Dispatchers.Main) { + isRefreshing = true } - // when both old and new is kotlin.collections.EmptyList - // moduleList update will don't trigger - if (oldModuleList === modules) { - isRefreshing = false - } + withContext(Dispatchers.IO) { + withTimeoutOrNull(TIMEOUT_MILLIS) { + while (!Platform.isAlive) { + delay(500) + } + } ?: run { + isRefreshing = false + Log.e(TAG, "Platform is not alive, aborting fetchModuleList") + return@withContext + } - Log.i(TAG, "load cost: ${SystemClock.elapsedRealtime() - start}, modules: $modules") + val start = SystemClock.elapsedRealtime() + val oldModuleList = modules + + kotlin.runCatching { + isOverlayAvailable = overlayFsAvailable() + val result = listModules() + Log.i(TAG, "result: $result") + + val array = JSONArray(result) + modules = (0 until array.length()) + .asSequence() + .map { array.getJSONObject(it) } + .map { obj -> + val id = obj.getString("id") + val config = id.asModuleConfig + + ModuleInfo( + id, + config.name ?: obj.optString("name"), + obj.optString("author", "Unknown"), + obj.optString("version", "Unknown"), + obj.optInt("versionCode", 0), + config.description ?: obj.optString("description"), + obj.getBoolean("enabled"), + obj.getBoolean("update"), + obj.getBoolean("remove"), + obj.optString("updateJson"), + obj.optBoolean("web"), + obj.optBoolean("action"), + obj.getString("dir_id"), + config + ) + }.toList() + isNeedRefresh = false + }.onFailure { e -> + Log.e(TAG, "fetchModuleList: ", e) + isRefreshing = false + } + + // when both old and new is kotlin.collections.EmptyList + // moduleList update will don't trigger + if (oldModuleList === modules) { + isRefreshing = false + } + + Log.i(TAG, "load cost: ${SystemClock.elapsedRealtime() - start}, modules: $modules") + } } }