You've already forked KernelSU-Next
mirror of
https://github.com/KernelSU-Next/KernelSU-Next.git
synced 2025-08-27 23:46:34 +00:00
manager: Add sort options on module's appbar (#2308)
module list will be sorted by options when these are enabled:  It will be very friendly and convenient when manager has many modules.
This commit is contained in:
committed by
Rifat Azad
parent
156b369862
commit
02f08f7971
@@ -36,12 +36,16 @@ import androidx.compose.material.icons.outlined.*
|
|||||||
import androidx.compose.material3.AlertDialog
|
import androidx.compose.material3.AlertDialog
|
||||||
import androidx.compose.material3.Button
|
import androidx.compose.material3.Button
|
||||||
import androidx.compose.material3.ButtonDefaults
|
import androidx.compose.material3.ButtonDefaults
|
||||||
|
import androidx.compose.material3.Checkbox
|
||||||
|
import androidx.compose.material3.DropdownMenu
|
||||||
|
import androidx.compose.material3.DropdownMenuItem
|
||||||
import androidx.compose.material3.ElevatedCard
|
import androidx.compose.material3.ElevatedCard
|
||||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||||
import androidx.compose.material3.ExtendedFloatingActionButton
|
import androidx.compose.material3.ExtendedFloatingActionButton
|
||||||
import androidx.compose.material3.FilledTonalButton
|
import androidx.compose.material3.FilledTonalButton
|
||||||
import androidx.compose.material3.HorizontalDivider
|
import androidx.compose.material3.HorizontalDivider
|
||||||
import androidx.compose.material3.Icon
|
import androidx.compose.material3.Icon
|
||||||
|
import androidx.compose.material3.IconButton
|
||||||
import androidx.compose.material3.MaterialTheme
|
import androidx.compose.material3.MaterialTheme
|
||||||
import androidx.compose.material3.Scaffold
|
import androidx.compose.material3.Scaffold
|
||||||
import androidx.compose.material3.SnackbarDuration
|
import androidx.compose.material3.SnackbarDuration
|
||||||
@@ -111,9 +115,13 @@ fun ModuleScreen(navigator: DestinationsNavigator) {
|
|||||||
val viewModel = viewModel<ModuleViewModel>()
|
val viewModel = viewModel<ModuleViewModel>()
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val snackBarHost = LocalSnackbarHost.current
|
val snackBarHost = LocalSnackbarHost.current
|
||||||
|
val scope = rememberCoroutineScope()
|
||||||
|
val prefs = context.getSharedPreferences("settings", Context.MODE_PRIVATE)
|
||||||
|
|
||||||
LaunchedEffect(Unit) {
|
LaunchedEffect(Unit) {
|
||||||
if (viewModel.moduleList.isEmpty() || viewModel.isNeedRefresh) {
|
if (viewModel.moduleList.isEmpty() || viewModel.isNeedRefresh) {
|
||||||
|
viewModel.sortEnabledFirst = prefs.getBoolean("module_sort_enabled_first", false)
|
||||||
|
viewModel.sortActionFirst = prefs.getBoolean("module_sort_action_first", false)
|
||||||
viewModel.fetchModuleList()
|
viewModel.fetchModuleList()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -135,6 +143,55 @@ fun ModuleScreen(navigator: DestinationsNavigator) {
|
|||||||
Scaffold(
|
Scaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
TopAppBar(
|
TopAppBar(
|
||||||
|
actions = {
|
||||||
|
var showDropdown by remember { mutableStateOf(false) }
|
||||||
|
IconButton(
|
||||||
|
onClick = { showDropdown = true },
|
||||||
|
) {
|
||||||
|
Icon(
|
||||||
|
imageVector = Icons.Filled.MoreVert,
|
||||||
|
contentDescription = stringResource(id = R.string.settings)
|
||||||
|
)
|
||||||
|
DropdownMenu(expanded = showDropdown, onDismissRequest = {
|
||||||
|
showDropdown = false
|
||||||
|
}) {
|
||||||
|
DropdownMenuItem(text = {
|
||||||
|
Text(stringResource(R.string.module_sort_action_first))
|
||||||
|
}, trailingIcon = {
|
||||||
|
Checkbox(viewModel.sortActionFirst, null)
|
||||||
|
}, onClick = {
|
||||||
|
viewModel.sortActionFirst =
|
||||||
|
!viewModel.sortActionFirst
|
||||||
|
prefs.edit()
|
||||||
|
.putBoolean(
|
||||||
|
"module_sort_action_first",
|
||||||
|
viewModel.sortActionFirst
|
||||||
|
)
|
||||||
|
.apply()
|
||||||
|
scope.launch {
|
||||||
|
viewModel.fetchModuleList()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
DropdownMenuItem(text = {
|
||||||
|
Text(stringResource(R.string.module_sort_enabled_first))
|
||||||
|
}, trailingIcon = {
|
||||||
|
Checkbox(viewModel.sortEnabledFirst, null)
|
||||||
|
}, onClick = {
|
||||||
|
viewModel.sortEnabledFirst =
|
||||||
|
!viewModel.sortEnabledFirst
|
||||||
|
prefs.edit()
|
||||||
|
.putBoolean(
|
||||||
|
"module_sort_enabled_first",
|
||||||
|
viewModel.sortEnabledFirst
|
||||||
|
)
|
||||||
|
.apply()
|
||||||
|
scope.launch {
|
||||||
|
viewModel.fetchModuleList()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
scrollBehavior = scrollBehavior,
|
scrollBehavior = scrollBehavior,
|
||||||
title = { Text(stringResource(R.string.module)) },
|
title = { Text(stringResource(R.string.module)) },
|
||||||
windowInsets = WindowInsets.safeDrawing.only(WindowInsetsSides.Top + WindowInsetsSides.Horizontal)
|
windowInsets = WindowInsets.safeDrawing.only(WindowInsetsSides.Top + WindowInsetsSides.Horizontal)
|
||||||
|
|||||||
@@ -14,8 +14,6 @@ import com.rifsxd.ksunext.ui.util.listModules
|
|||||||
import com.rifsxd.ksunext.ui.util.overlayFsAvailable
|
import com.rifsxd.ksunext.ui.util.overlayFsAvailable
|
||||||
import org.json.JSONArray
|
import org.json.JSONArray
|
||||||
import org.json.JSONObject
|
import org.json.JSONObject
|
||||||
import java.text.Collator
|
|
||||||
import java.util.Locale
|
|
||||||
|
|
||||||
class ModuleViewModel : ViewModel() {
|
class ModuleViewModel : ViewModel() {
|
||||||
|
|
||||||
@@ -52,8 +50,14 @@ class ModuleViewModel : ViewModel() {
|
|||||||
var isRefreshing by mutableStateOf(false)
|
var isRefreshing by mutableStateOf(false)
|
||||||
private set
|
private set
|
||||||
|
|
||||||
|
var sortEnabledFirst by mutableStateOf(false)
|
||||||
|
var sortActionFirst by mutableStateOf(false)
|
||||||
val moduleList by derivedStateOf {
|
val moduleList by derivedStateOf {
|
||||||
val comparator = compareBy(Collator.getInstance(Locale.getDefault()), ModuleInfo::id)
|
val comparator =
|
||||||
|
compareBy<ModuleInfo>(
|
||||||
|
{ if (sortEnabledFirst) !it.enabled else 0 },
|
||||||
|
{ if (sortActionFirst) !it.hasWebUi && !it.hasActionScript else 0 },
|
||||||
|
{ it.id })
|
||||||
modules.sortedWith(comparator).also {
|
modules.sortedWith(comparator).also {
|
||||||
isRefreshing = false
|
isRefreshing = false
|
||||||
}
|
}
|
||||||
@@ -159,4 +163,4 @@ class ModuleViewModel : ViewModel() {
|
|||||||
|
|
||||||
return Triple(zipUrl, version, changelog)
|
return Triple(zipUrl, version, changelog)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -35,6 +35,8 @@
|
|||||||
<string name="module">模块</string>
|
<string name="module">模块</string>
|
||||||
<string name="confirm_module_installation">确认安装</string>
|
<string name="confirm_module_installation">确认安装</string>
|
||||||
<string name="module_install_prompt_with_name">是否要继续安装模块 %1$s ?</string>
|
<string name="module_install_prompt_with_name">是否要继续安装模块 %1$s ?</string>
|
||||||
|
<string name="module_sort_action_first">可执行优先</string>
|
||||||
|
<string name="module_sort_enabled_first">已启用优先</string>
|
||||||
<string name="uninstall">卸载</string>
|
<string name="uninstall">卸载</string>
|
||||||
<string name="restore">重启</string>
|
<string name="restore">重启</string>
|
||||||
<string name="module_install">安装</string>
|
<string name="module_install">安装</string>
|
||||||
@@ -156,4 +158,4 @@
|
|||||||
<string name="selected_lkm">选择的 LKM: %s</string>
|
<string name="selected_lkm">选择的 LKM: %s</string>
|
||||||
<string name="save_log">保存日志</string>
|
<string name="save_log">保存日志</string>
|
||||||
<string name="log_saved">日志已保存</string>
|
<string name="log_saved">日志已保存</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -36,6 +36,8 @@
|
|||||||
<string name="module">Module</string>
|
<string name="module">Module</string>
|
||||||
<string name="confirm_module_installation">Confirm Installation</string>
|
<string name="confirm_module_installation">Confirm Installation</string>
|
||||||
<string name="module_install_prompt_with_name">Do you want to continue installing module %1$s?</string>
|
<string name="module_install_prompt_with_name">Do you want to continue installing module %1$s?</string>
|
||||||
|
<string name="module_sort_action_first">Sort (Action First)</string>
|
||||||
|
<string name="module_sort_enabled_first">Sort (Enabled First)</string>
|
||||||
<string name="uninstall">Uninstall</string>
|
<string name="uninstall">Uninstall</string>
|
||||||
<string name="restore">Restore</string>
|
<string name="restore">Restore</string>
|
||||||
<string name="module_install">Install</string>
|
<string name="module_install">Install</string>
|
||||||
|
|||||||
Reference in New Issue
Block a user