package net.bluemangoo.indpjsk.ui import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.material3.Checkbox import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.painterResource import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.withContext import net.bluemangoo.indpjsk.R import net.bluemangoo.indpjsk.data.AppEntry import net.bluemangoo.indpjsk.data.InstalledApps @OptIn(ExperimentalMaterial3Api::class) @Composable fun AppSelectionScreen( selected: Set, onToggle: (AppEntry) -> Unit, onBack: () -> Unit, ) { val context = LocalContext.current var allApps by remember { mutableStateOf>(emptyList()) } var loading by remember { mutableStateOf(true) } var query by remember { mutableStateOf("") } LaunchedEffect(Unit) { val list = withContext(Dispatchers.IO) { InstalledApps.list(context) } allApps = list loading = false } val filtered = remember(query, allApps) { if (query.isBlank()) { allApps } else { allApps.filter { it.label.contains(query, ignoreCase = true) || it.packageName.contains(query, ignoreCase = true) } } } Scaffold( topBar = { TopAppBar( title = { Text("选择忽略的应用") }, navigationIcon = { IconButton(onClick = onBack) { Icon( painter = painterResource(R.drawable.arrow_back_24px), contentDescription = "返回" ) } } ) } ) { padding -> Column( modifier = Modifier .padding(padding) .fillMaxSize() ) { OutlinedTextField( value = query, onValueChange = { query = it }, modifier = Modifier .fillMaxWidth() .padding(horizontal = 16.dp, vertical = 8.dp), placeholder = { Text("搜索应用名称或包名…") }, singleLine = true ) if (loading) { Box( modifier = Modifier .weight(1f) .fillMaxWidth(), contentAlignment = Alignment.Center ) { CircularProgressIndicator() } } else if (filtered.isEmpty()) { Box( modifier = Modifier .weight(1f) .fillMaxWidth(), contentAlignment = Alignment.Center ) { Text( "没有找到相关的应用", color = MaterialTheme.colorScheme.onSurfaceVariant ) } } else { LazyColumn( modifier = Modifier .weight(1f) .fillMaxWidth() ) { items(filtered, key = { it.packageName }) { app -> val checked = app.packageName in selected Row( modifier = Modifier .fillMaxWidth() .clickable { onToggle(app) } .padding(horizontal = 16.dp, vertical = 12.dp), verticalAlignment = Alignment.CenterVertically ) { AppIcon(icon = app.icon, label = app.label) Spacer(modifier = Modifier.width(16.dp)) Column( modifier = Modifier.weight(1f), verticalArrangement = Arrangement.spacedBy(2.dp) ) { Text( text = app.label, style = MaterialTheme.typography.bodyLarge, maxLines = 1, overflow = TextOverflow.Ellipsis ) Text( text = app.packageName, style = MaterialTheme.typography.bodySmall, color = MaterialTheme.colorScheme.onSurfaceVariant, maxLines = 1, overflow = TextOverflow.Ellipsis ) } Checkbox( checked = checked, onCheckedChange = { onToggle(app) } ) } } } } } } }