diff --git a/manager/app/src/main/java/com/sukisu/ultra/ui/screen/Home.kt b/manager/app/src/main/java/com/sukisu/ultra/ui/screen/Home.kt index 3e49dcb2..39e50987 100644 --- a/manager/app/src/main/java/com/sukisu/ultra/ui/screen/Home.kt +++ b/manager/app/src/main/java/com/sukisu/ultra/ui/screen/Home.kt @@ -6,61 +6,124 @@ import android.os.Build import android.os.PowerManager import android.system.Os import androidx.annotation.StringRes -import androidx.compose.animation.* -import androidx.compose.animation.core.* +import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.core.Spring +import androidx.compose.animation.core.spring +import androidx.compose.animation.expandVertically +import androidx.compose.animation.fadeIn +import androidx.compose.animation.fadeOut +import androidx.compose.animation.shrinkVertically import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.WindowInsets +import androidx.compose.foundation.layout.WindowInsetsSides +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.only +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.safeDrawing +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.layout.wrapContentHeight import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.* -import androidx.compose.material.icons.outlined.* -import androidx.compose.material3.* -import androidx.compose.runtime.* +import androidx.compose.material.icons.filled.Android +import androidx.compose.material.icons.filled.Archive +import androidx.compose.material.icons.filled.Code +import androidx.compose.material.icons.filled.Favorite +import androidx.compose.material.icons.filled.Info +import androidx.compose.material.icons.filled.Memory +import androidx.compose.material.icons.filled.PhoneAndroid +import androidx.compose.material.icons.filled.Refresh +import androidx.compose.material.icons.filled.School +import androidx.compose.material.icons.filled.Security +import androidx.compose.material.icons.filled.Settings +import androidx.compose.material.icons.filled.Storage +import androidx.compose.material.icons.filled.Warning +import androidx.compose.material.icons.outlined.Block +import androidx.compose.material.icons.outlined.CheckCircle +import androidx.compose.material.icons.outlined.Info +import androidx.compose.material.icons.outlined.Warning +import androidx.compose.material3.CardDefaults +import androidx.compose.material3.DropdownMenu +import androidx.compose.material3.DropdownMenuItem +import androidx.compose.material3.ElevatedCard +import androidx.compose.material3.ExperimentalMaterial3Api +import androidx.compose.material3.Icon +import androidx.compose.material3.IconButton +import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.Scaffold +import androidx.compose.material3.Text +import androidx.compose.material3.TopAppBar +import androidx.compose.material3.TopAppBarDefaults +import androidx.compose.material3.TopAppBarScrollBehavior +import androidx.compose.material3.rememberTopAppBarState +import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableIntStateOf +import androidx.compose.runtime.mutableLongStateOf +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.produceState +import androidx.compose.runtime.remember +import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue +import androidx.compose.runtime.snapshotFlow import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier +import androidx.compose.ui.composed import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.shadow import androidx.compose.ui.graphics.Color +import androidx.compose.ui.graphics.vector.ImageVector import androidx.compose.ui.input.nestedscroll.nestedScroll -import androidx.compose.ui.platform.* +import androidx.compose.ui.platform.LocalContext +import androidx.compose.ui.platform.LocalUriHandler import androidx.compose.ui.res.stringResource -import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp +import androidx.core.content.edit import androidx.core.content.pm.PackageInfoCompat import com.ramcosta.composedestinations.annotation.Destination import com.ramcosta.composedestinations.annotation.RootGraph import com.ramcosta.composedestinations.generated.destinations.InstallScreenDestination import com.ramcosta.composedestinations.navigation.DestinationsNavigator -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext -import com.sukisu.ultra.* +import com.sukisu.ultra.KernelVersion +import com.sukisu.ultra.Natives import com.sukisu.ultra.R +import com.sukisu.ultra.getKernelVersion +import com.sukisu.ultra.ksuApp import com.sukisu.ultra.ui.component.rememberConfirmDialog -import com.sukisu.ultra.ui.util.* -import com.sukisu.ultra.ui.util.module.LatestVersionInfo -import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.Text -import com.sukisu.ultra.ui.theme.getCardColors -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.getValue -import androidx.compose.runtime.setValue -import androidx.compose.animation.AnimatedVisibility -import androidx.compose.animation.fadeOut -import androidx.compose.animation.shrinkVertically -import androidx.compose.runtime.saveable.rememberSaveable -import androidx.compose.ui.composed -import androidx.compose.ui.graphics.graphicsLayer -import androidx.compose.ui.graphics.vector.ImageVector import com.sukisu.ultra.ui.theme.CardConfig -import androidx.core.content.edit +import com.sukisu.ultra.ui.theme.getCardColors +import com.sukisu.ultra.ui.util.checkNewVersion +import com.sukisu.ultra.ui.util.getKpmModuleCount +import com.sukisu.ultra.ui.util.getKpmVersion +import com.sukisu.ultra.ui.util.getModuleCount +import com.sukisu.ultra.ui.util.getSELinuxStatus +import com.sukisu.ultra.ui.util.getSuSFS +import com.sukisu.ultra.ui.util.getSuSFSFeatures +import com.sukisu.ultra.ui.util.getSuSFSVariant +import com.sukisu.ultra.ui.util.getSuSFSVersion +import com.sukisu.ultra.ui.util.getSuperuserCount +import com.sukisu.ultra.ui.util.module.LatestVersionInfo +import com.sukisu.ultra.ui.util.reboot +import com.sukisu.ultra.ui.util.rootAvailable +import com.sukisu.ultra.ui.util.susfsSUS_SU_Mode +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.FlowPreview +import kotlinx.coroutines.flow.debounce +import kotlinx.coroutines.withContext import java.io.BufferedReader import java.io.InputStreamReader import java.util.zip.GZIPInputStream import kotlin.random.Random -@OptIn(ExperimentalMaterial3Api::class) +@OptIn(ExperimentalMaterial3Api::class, FlowPreview::class) @Destination(start = true) @Composable fun HomeScreen(navigator: DestinationsNavigator) { @@ -89,7 +152,7 @@ fun HomeScreen(navigator: DestinationsNavigator) { val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior(rememberTopAppBarState()) val isManager = Natives.becomeManager(ksuApp.packageName) - val deviceModel = getDeviceModel(context) + val deviceModel = getDeviceModel() val ksuVersion = if (isManager) Natives.version else null val zako = "一.*加.*A.*c.*e.*5.*P.*r.*o".toRegex().matches(deviceModel) val isVersion = ksuVersion == 12777 @@ -106,6 +169,10 @@ fun HomeScreen(navigator: DestinationsNavigator) { } } + val scrollState = rememberScrollState() + val debounceTime = 100L + var lastScrollTime by remember { mutableLongStateOf(0L) } + Scaffold( topBar = { TopBar( @@ -121,10 +188,9 @@ fun HomeScreen(navigator: DestinationsNavigator) { Column( modifier = Modifier .padding(innerPadding) - .graphicsLayer(clip = true) .disableOverscroll() .nestedScroll(scrollBehavior.nestedScrollConnection) - .verticalScroll(rememberScrollState()) + .verticalScroll(scrollState) .padding(top = 12.dp) .padding(horizontal = 16.dp), verticalArrangement = Arrangement.spacedBy(12.dp) @@ -221,6 +287,21 @@ fun HomeScreen(navigator: DestinationsNavigator) { Spacer(Modifier.height(16.dp)) } } + + // 防抖逻辑 + LaunchedEffect(scrollState) { + snapshotFlow { scrollState.isScrollInProgress } + .debounce(debounceTime) + .collect { isScrolling -> + if (isScrolling) { + val currentTime = System.currentTimeMillis() + if (currentTime - lastScrollTime > debounceTime) { + lastScrollTime = currentTime + // 在这里可以添加滚动时的逻辑 + } + } + } + } } @Composable @@ -761,9 +842,7 @@ private fun InfoCard() { fun InfoCardItem( label: String, content: String, - icon: ImageVector = Icons.Default.Info, - maxLines: Int = 2, - overflow: TextOverflow = TextOverflow.Ellipsis + icon: ImageVector = Icons.Default.Info ) { contents.appendLine(label).appendLine(content).appendLine() Row( @@ -814,7 +893,7 @@ private fun InfoCard() { ) } - val deviceModel = getDeviceModel(context) + val deviceModel = getDeviceModel() InfoCardItem( stringResource(R.string.home_device_model), deviceModel, @@ -853,9 +932,7 @@ private fun InfoCard() { InfoCardItem( stringResource(R.string.home_kpm_version), displayVersion, - icon = Icons.Default.Code, - Int.MAX_VALUE, - TextOverflow.Clip + icon = Icons.Default.Code ) } } @@ -883,9 +960,7 @@ private fun InfoCard() { InfoCardItem( stringResource(R.string.home_susfs_version), infoText, - icon = Icons.Default.Storage, - Int.MAX_VALUE, - TextOverflow.Clip + icon = Icons.Default.Storage ) } } @@ -924,7 +999,7 @@ private fun WarningCardPreview() { } @SuppressLint("PrivateApi") -private fun getDeviceModel(context: Context): String { +private fun getDeviceModel(): String { return try { val systemProperties = Class.forName("android.os.SystemProperties") val getMethod = systemProperties.getMethod("get", String::class.java, String::class.java)