manager: redo fetchAppList onCreate

This commit is contained in:
YuKongA
2025-11-27 13:46:32 +08:00
committed by shirkneko
parent 3853928305
commit de04ea9db0
7 changed files with 40 additions and 41 deletions

View File

@@ -2,8 +2,10 @@ package com.sukisu.ultra
import android.app.Application import android.app.Application
import android.system.Os import android.system.Os
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.ViewModelStore import androidx.lifecycle.ViewModelStore
import androidx.lifecycle.ViewModelStoreOwner import androidx.lifecycle.ViewModelStoreOwner
import me.weishu.kernelsu.ui.viewmodel.SuperUserViewModel
import okhttp3.Cache import okhttp3.Cache
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import java.io.File import java.io.File
@@ -20,6 +22,9 @@ class KernelSUApplication : Application(), ViewModelStoreOwner {
super.onCreate() super.onCreate()
ksuApp = this ksuApp = this
val superUserViewModel = ViewModelProvider(this)[SuperUserViewModel::class.java]
superUserViewModel.loadAppList()
val webroot = File(dataDir, "webroot") val webroot = File(dataDir, "webroot")
if (!webroot.exists()) { if (!webroot.exists()) {
webroot.mkdir() webroot.mkdir()

View File

@@ -81,14 +81,11 @@ import top.yukonga.miuix.kmp.basic.BasicComponent
import top.yukonga.miuix.kmp.basic.Card import top.yukonga.miuix.kmp.basic.Card
import top.yukonga.miuix.kmp.basic.CardDefaults import top.yukonga.miuix.kmp.basic.CardDefaults
import top.yukonga.miuix.kmp.basic.Icon import top.yukonga.miuix.kmp.basic.Icon
import top.yukonga.miuix.kmp.basic.IconButton
import top.yukonga.miuix.kmp.basic.MiuixScrollBehavior import top.yukonga.miuix.kmp.basic.MiuixScrollBehavior
import top.yukonga.miuix.kmp.basic.Scaffold import top.yukonga.miuix.kmp.basic.Scaffold
import top.yukonga.miuix.kmp.basic.ScrollBehavior import top.yukonga.miuix.kmp.basic.ScrollBehavior
import top.yukonga.miuix.kmp.basic.Text import top.yukonga.miuix.kmp.basic.Text
import top.yukonga.miuix.kmp.basic.TopAppBar import top.yukonga.miuix.kmp.basic.TopAppBar
import top.yukonga.miuix.kmp.icon.MiuixIcons
import top.yukonga.miuix.kmp.icon.icons.useful.Save
import top.yukonga.miuix.kmp.theme.MiuixTheme import top.yukonga.miuix.kmp.theme.MiuixTheme
import top.yukonga.miuix.kmp.theme.MiuixTheme.colorScheme import top.yukonga.miuix.kmp.theme.MiuixTheme.colorScheme
import top.yukonga.miuix.kmp.theme.MiuixTheme.isDynamicColor import top.yukonga.miuix.kmp.theme.MiuixTheme.isDynamicColor
@@ -284,18 +281,6 @@ private fun TopBar(
color = Color.Transparent, color = Color.Transparent,
title = stringResource(R.string.app_name), title = stringResource(R.string.app_name),
actions = { actions = {
if (kernelVersion.isGKI()) {
IconButton(
modifier = Modifier.padding(end = 8.dp),
onClick = onInstallClick,
) {
Icon(
imageVector = MiuixIcons.Useful.Save,
contentDescription = stringResource(id = R.string.install),
tint = colorScheme.onBackground
)
}
}
RebootListPopup( RebootListPopup(
modifier = Modifier.padding(end = 16.dp), modifier = Modifier.padding(end = 16.dp),
) )

View File

@@ -139,7 +139,7 @@ import top.yukonga.miuix.kmp.extra.DropdownImpl
import top.yukonga.miuix.kmp.icon.MiuixIcons import top.yukonga.miuix.kmp.icon.MiuixIcons
import top.yukonga.miuix.kmp.icon.icons.useful.Delete import top.yukonga.miuix.kmp.icon.icons.useful.Delete
import top.yukonga.miuix.kmp.icon.icons.useful.ImmersionMore import top.yukonga.miuix.kmp.icon.icons.useful.ImmersionMore
import top.yukonga.miuix.kmp.icon.icons.useful.New import top.yukonga.miuix.kmp.icon.icons.useful.Save
import top.yukonga.miuix.kmp.icon.icons.useful.Undo import top.yukonga.miuix.kmp.icon.icons.useful.Undo
import top.yukonga.miuix.kmp.theme.MiuixTheme.colorScheme import top.yukonga.miuix.kmp.theme.MiuixTheme.colorScheme
import top.yukonga.miuix.kmp.utils.getWindowSize import top.yukonga.miuix.kmp.utils.getWindowSize
@@ -161,13 +161,19 @@ fun ModulePager(
val modules = viewModel.moduleList val modules = viewModel.moduleList
LaunchedEffect(navigator) { LaunchedEffect(Unit) {
if (viewModel.moduleList.isEmpty() || viewModel.searchResults.value.isEmpty() || viewModel.isNeedRefresh) { when {
viewModel.moduleList.isEmpty() -> {
viewModel.checkModuleUpdate = prefs.getBoolean("module_check_update", true) viewModel.checkModuleUpdate = prefs.getBoolean("module_check_update", true)
viewModel.sortEnabledFirst = prefs.getBoolean("module_sort_enabled_first", false) viewModel.sortEnabledFirst = prefs.getBoolean("module_sort_enabled_first", false)
viewModel.sortActionFirst = prefs.getBoolean("module_sort_action_first", false) viewModel.sortActionFirst = prefs.getBoolean("module_sort_action_first", false)
viewModel.fetchModuleList() viewModel.fetchModuleList()
} }
viewModel.isNeedRefresh -> {
viewModel.fetchModuleList()
}
}
} }
LaunchedEffect(searchStatus.searchText) { LaunchedEffect(searchStatus.searchText) {
@@ -470,7 +476,7 @@ fun ModulePager(
}, },
) { ) {
Icon( Icon(
imageVector = MiuixIcons.Useful.New, imageVector = MiuixIcons.Useful.Save,
tint = colorScheme.onSurface, tint = colorScheme.onSurface,
contentDescription = stringResource(id = R.string.settings) contentDescription = stringResource(id = R.string.settings)
) )

View File

@@ -90,7 +90,7 @@ import top.yukonga.miuix.kmp.basic.TopAppBar
import top.yukonga.miuix.kmp.basic.rememberPullToRefreshState import top.yukonga.miuix.kmp.basic.rememberPullToRefreshState
import top.yukonga.miuix.kmp.icon.MiuixIcons import top.yukonga.miuix.kmp.icon.MiuixIcons
import top.yukonga.miuix.kmp.icon.icons.useful.Back import top.yukonga.miuix.kmp.icon.icons.useful.Back
import top.yukonga.miuix.kmp.icon.icons.useful.Redo import top.yukonga.miuix.kmp.icon.icons.useful.NavigatorSwitch
import top.yukonga.miuix.kmp.icon.icons.useful.Save import top.yukonga.miuix.kmp.icon.icons.useful.Save
import top.yukonga.miuix.kmp.theme.MiuixTheme.colorScheme import top.yukonga.miuix.kmp.theme.MiuixTheme.colorScheme
import top.yukonga.miuix.kmp.utils.PressFeedbackType import top.yukonga.miuix.kmp.utils.PressFeedbackType
@@ -563,7 +563,7 @@ fun ModuleRepoDetailScreen(
onClick = { uriHandler.openUri(module.homepageUrl) } onClick = { uriHandler.openUri(module.homepageUrl) }
) { ) {
Icon( Icon(
imageVector = MiuixIcons.Useful.Redo, imageVector = MiuixIcons.Useful.NavigatorSwitch,
contentDescription = null, contentDescription = null,
tint = colorScheme.onBackground tint = colorScheme.onBackground
) )

View File

@@ -115,10 +115,10 @@ fun SuperUserPager(
val context = LocalContext.current val context = LocalContext.current
val prefs = context.getSharedPreferences("settings", Context.MODE_PRIVATE) val prefs = context.getSharedPreferences("settings", Context.MODE_PRIVATE)
LaunchedEffect(navigator) { LaunchedEffect(Unit) {
if (viewModel.appList.value.isEmpty() || viewModel.searchResults.value.isEmpty()) { if (viewModel.appList.value.isEmpty() || viewModel.isRefreshing) {
viewModel.showSystemApps = prefs.getBoolean("show_system_apps", false) viewModel.showSystemApps = prefs.getBoolean("show_system_apps", false)
viewModel.fetchAppList() viewModel.loadAppList()
} }
} }
@@ -274,7 +274,7 @@ fun SuperUserPager(
LaunchedEffect(isRefreshing) { LaunchedEffect(isRefreshing) {
if (isRefreshing) { if (isRefreshing) {
delay(350) delay(350)
viewModel.fetchAppList() viewModel.loadAppList()
isRefreshing = false isRefreshing = false
} }
} }

View File

@@ -19,9 +19,13 @@ import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf 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 com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.Shell
import com.topjohnwu.superuser.ipc.RootService import com.topjohnwu.superuser.ipc.RootService
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.coroutines.flow.asStateFlow
import kotlinx.coroutines.launch
import kotlinx.coroutines.sync.Mutex import kotlinx.coroutines.sync.Mutex
import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.sync.withLock
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
@@ -65,6 +69,7 @@ class SuperUserViewModel : ViewModel() {
private var _appList = mutableStateOf<List<AppInfo>>(emptyList()) private var _appList = mutableStateOf<List<AppInfo>>(emptyList())
val appList: State<List<AppInfo>> = _appList val appList: State<List<AppInfo>> = _appList
private val _searchStatus = mutableStateOf(SearchStatus("")) private val _searchStatus = mutableStateOf(SearchStatus(""))
val searchStatus: State<SearchStatus> = _searchStatus val searchStatus: State<SearchStatus> = _searchStatus
@@ -122,13 +127,7 @@ class SuperUserViewModel : ViewModel() {
} }
} }
if (_searchResults.value == result) {
fetchAppList()
updateSearchText(text)
} else {
_searchResults.value = result _searchResults.value = result
}
_searchStatus.value.resultStatus = if (result.isEmpty()) { _searchStatus.value.resultStatus = if (result.isEmpty()) {
SearchStatus.ResultStatus.EMPTY SearchStatus.ResultStatus.EMPTY
} else { } else {
@@ -236,4 +235,10 @@ class SuperUserViewModel : ViewModel() {
} }
} }
} }
fun loadAppList() {
viewModelScope.launch {
fetchAppList()
}
}
} }

View File

@@ -18,7 +18,6 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
import androidx.core.view.WindowInsetsCompat import androidx.core.view.WindowInsetsCompat
import androidx.lifecycle.ViewModelProvider
import androidx.lifecycle.lifecycleScope import androidx.lifecycle.lifecycleScope
import androidx.webkit.WebViewAssetLoader import androidx.webkit.WebViewAssetLoader
import com.topjohnwu.superuser.Shell import com.topjohnwu.superuser.Shell
@@ -57,13 +56,12 @@ class WebUIActivity : ComponentActivity() {
} }
} }
val superUserViewModel = ViewModelProvider(this)[SuperUserViewModel::class.java]
lifecycleScope.launch { lifecycleScope.launch {
superUserViewModel.fetchAppList() if (SuperUserViewModel.apps.isNotEmpty()) {
setupWebView() setupWebView()
} }
} }
}
private suspend fun setupWebView() { private suspend fun setupWebView() {
val moduleId = intent.getStringExtra("id")!! val moduleId = intent.getStringExtra("id")!!