manager: better handle webui engine select
- Optimize the flashback problem caused by null pointer Co-authored-by: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com> Co-authored-by: Der_Googler <54764558+DerGoogler@users.noreply.github.com> Signed-off-by: ShirkNeko <109797057+ShirkNeko@users.noreply.github.com>
This commit is contained in:
@@ -72,6 +72,8 @@ import com.sukisu.ultra.ui.theme.CardConfig.cardElevation
|
|||||||
import com.sukisu.ultra.ui.webui.WebUIXActivity
|
import com.sukisu.ultra.ui.webui.WebUIXActivity
|
||||||
import com.dergoogler.mmrl.platform.Platform
|
import com.dergoogler.mmrl.platform.Platform
|
||||||
import androidx.core.net.toUri
|
import androidx.core.net.toUri
|
||||||
|
import com.dergoogler.mmrl.platform.model.ModuleConfig
|
||||||
|
import com.dergoogler.mmrl.platform.model.ModuleConfig.Companion.asModuleConfig
|
||||||
|
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class)
|
||||||
@@ -83,6 +85,7 @@ fun ModuleScreen(navigator: DestinationsNavigator) {
|
|||||||
val snackBarHost = LocalSnackbarHost.current
|
val snackBarHost = LocalSnackbarHost.current
|
||||||
val scope = rememberCoroutineScope()
|
val scope = rememberCoroutineScope()
|
||||||
val confirmDialog = rememberConfirmDialog()
|
val confirmDialog = rememberConfirmDialog()
|
||||||
|
var lastClickTime by remember { mutableStateOf(0L) }
|
||||||
|
|
||||||
val selectZipLauncher = rememberLauncherForActivityResult(
|
val selectZipLauncher = rememberLauncherForActivityResult(
|
||||||
contract = ActivityResultContracts.StartActivityForResult()
|
contract = ActivityResultContracts.StartActivityForResult()
|
||||||
@@ -142,7 +145,7 @@ fun ModuleScreen(navigator: DestinationsNavigator) {
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
val uri = data.data ?: return@launch
|
val uri = data.data ?: return@launch
|
||||||
// 单个安装模块
|
// 单个安装模块
|
||||||
try {
|
try {
|
||||||
if (!ModuleUtils.isUriAccessible(context, uri)) {
|
if (!ModuleUtils.isUriAccessible(context, uri)) {
|
||||||
snackBarHost.showSnackbar("Unable to access selected module files")
|
snackBarHost.showSnackbar("Unable to access selected module files")
|
||||||
@@ -371,24 +374,48 @@ fun ModuleScreen(navigator: DestinationsNavigator) {
|
|||||||
navigator.navigate(FlashScreenDestination(FlashIt.FlashModule(it)))
|
navigator.navigate(FlashScreenDestination(FlashIt.FlashModule(it)))
|
||||||
},
|
},
|
||||||
onClickModule = { id, name, hasWebUi ->
|
onClickModule = { id, name, hasWebUi ->
|
||||||
|
val currentTime = System.currentTimeMillis()
|
||||||
|
if (currentTime - lastClickTime < 600) {
|
||||||
|
Log.d("ModuleScreen", "Click too fast, ignoring")
|
||||||
|
return@ModuleList
|
||||||
|
}
|
||||||
|
lastClickTime = currentTime
|
||||||
|
|
||||||
if (hasWebUi) {
|
if (hasWebUi) {
|
||||||
val wxEngine = Intent(context, WebUIXActivity::class.java)
|
try {
|
||||||
.setData("kernelsu://webuix/$id".toUri())
|
val wxEngine = Intent(context, WebUIXActivity::class.java)
|
||||||
.putExtra("id", id)
|
.setData("kernelsu://webuix/$id".toUri())
|
||||||
.putExtra("name", name)
|
.putExtra("id", id)
|
||||||
|
.putExtra("name", name)
|
||||||
|
|
||||||
val ksuEngine = Intent(context, WebUIActivity::class.java)
|
val ksuEngine = Intent(context, WebUIActivity::class.java)
|
||||||
.setData("kernelsu://webui/$id".toUri())
|
.setData("kernelsu://webui/$id".toUri())
|
||||||
.putExtra("id", id)
|
.putExtra("id", id)
|
||||||
.putExtra("name", name)
|
.putExtra("name", name)
|
||||||
|
|
||||||
webUILauncher.launch(
|
val config = try {
|
||||||
if (prefs.getBoolean("use_webuix", true) && Platform.isAlive) {
|
id.asModuleConfig
|
||||||
wxEngine
|
} catch (e: Exception) {
|
||||||
} else {
|
Log.e("ModuleScreen", "Failed to get config from id: $id", e)
|
||||||
ksuEngine
|
null
|
||||||
}
|
}
|
||||||
)
|
|
||||||
|
val engine = config?.getWebuiEngine(context)
|
||||||
|
val selectedEngine = when (engine) {
|
||||||
|
"wx" -> wxEngine
|
||||||
|
"ksu" -> ksuEngine
|
||||||
|
null -> if (prefs.getBoolean("use_webuix", true) && Platform.isAlive) wxEngine else ksuEngine
|
||||||
|
else -> ksuEngine
|
||||||
|
}
|
||||||
|
|
||||||
|
webUILauncher.launch(selectedEngine)
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e("ModuleScreen", "Error launching WebUI: ${e.message}", e)
|
||||||
|
scope.launch {
|
||||||
|
snackBarHost.showSnackbar("Error launching WebUI: ${e.message}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return@ModuleList
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
context = context,
|
context = context,
|
||||||
@@ -902,7 +929,8 @@ fun ModuleItemPreview() {
|
|||||||
updateJson = "",
|
updateJson = "",
|
||||||
hasWebUi = false,
|
hasWebUi = false,
|
||||||
hasActionScript = false,
|
hasActionScript = false,
|
||||||
dirId = "dirId"
|
dirId = "dirId",
|
||||||
|
config = ModuleConfig(),
|
||||||
)
|
)
|
||||||
ModuleItem(EmptyDestinationsNavigator, module, "", {}, {}, {}, {})
|
ModuleItem(EmptyDestinationsNavigator, module, "", {}, {}, {}, {})
|
||||||
}
|
}
|
||||||
@@ -8,10 +8,13 @@ import androidx.compose.runtime.mutableStateOf
|
|||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
|
import com.dergoogler.mmrl.platform.model.ModuleConfig
|
||||||
|
import com.dergoogler.mmrl.platform.model.ModuleConfig.Companion.asModuleConfig
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import com.sukisu.ultra.ui.util.HanziToPinyin
|
import com.sukisu.ultra.ui.util.HanziToPinyin
|
||||||
import com.sukisu.ultra.ui.util.listModules
|
import com.sukisu.ultra.ui.util.listModules
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
import org.json.JSONArray
|
import org.json.JSONArray
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
import java.text.Collator
|
import java.text.Collator
|
||||||
@@ -40,6 +43,7 @@ class ModuleViewModel : ViewModel() {
|
|||||||
val hasWebUi: Boolean,
|
val hasWebUi: Boolean,
|
||||||
val hasActionScript: Boolean,
|
val hasActionScript: Boolean,
|
||||||
val dirId: String, // real module id (dir name)
|
val dirId: String, // real module id (dir name)
|
||||||
|
var config: ModuleConfig? = null,
|
||||||
)
|
)
|
||||||
|
|
||||||
var isRefreshing by mutableStateOf(false)
|
var isRefreshing by mutableStateOf(false)
|
||||||
@@ -103,6 +107,39 @@ class ModuleViewModel : ViewModel() {
|
|||||||
obj.getString("dir_id")
|
obj.getString("dir_id")
|
||||||
)
|
)
|
||||||
}.toList()
|
}.toList()
|
||||||
|
launch {
|
||||||
|
modules.forEach { module ->
|
||||||
|
withContext(Dispatchers.IO) {
|
||||||
|
try {
|
||||||
|
runCatching {
|
||||||
|
module.config = module.id.asModuleConfig
|
||||||
|
}.onFailure { e ->
|
||||||
|
Log.e(TAG, "Failed to load config from id for module ${module.id}", e)
|
||||||
|
}
|
||||||
|
if (module.config == null) {
|
||||||
|
runCatching {
|
||||||
|
module.config = module.name.asModuleConfig
|
||||||
|
}.onFailure { e ->
|
||||||
|
Log.e(TAG, "Failed to load config from name for module ${module.id}", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (module.config == null) {
|
||||||
|
runCatching {
|
||||||
|
module.config = module.description.asModuleConfig
|
||||||
|
}.onFailure { e ->
|
||||||
|
Log.e(TAG, "Failed to load config from description for module ${module.id}", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (module.config == null) {
|
||||||
|
module.config = ModuleConfig()
|
||||||
|
}
|
||||||
|
} catch (e: Exception) {
|
||||||
|
Log.e(TAG, "Failed to load any config for module ${module.id}", e)
|
||||||
|
module.config = ModuleConfig()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
isNeedRefresh = false
|
isNeedRefresh = false
|
||||||
}.onFailure { e ->
|
}.onFailure { e ->
|
||||||
Log.e(TAG, "fetchModuleList: ", e)
|
Log.e(TAG, "fetchModuleList: ", e)
|
||||||
|
|||||||
Reference in New Issue
Block a user