Optimize the HomeScreen component, refactor the device model acquisition logic, add anti-shake scrolling processing, clean up unused imports
This commit is contained in:
@@ -6,61 +6,124 @@ import android.os.Build
|
|||||||
import android.os.PowerManager
|
import android.os.PowerManager
|
||||||
import android.system.Os
|
import android.system.Os
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import androidx.compose.animation.*
|
import androidx.compose.animation.AnimatedVisibility
|
||||||
import androidx.compose.animation.core.*
|
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.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.rememberScrollState
|
||||||
import androidx.compose.foundation.verticalScroll
|
import androidx.compose.foundation.verticalScroll
|
||||||
import androidx.compose.material.icons.Icons
|
import androidx.compose.material.icons.Icons
|
||||||
import androidx.compose.material.icons.filled.*
|
import androidx.compose.material.icons.filled.Android
|
||||||
import androidx.compose.material.icons.outlined.*
|
import androidx.compose.material.icons.filled.Archive
|
||||||
import androidx.compose.material3.*
|
import androidx.compose.material.icons.filled.Code
|
||||||
import androidx.compose.runtime.*
|
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.Alignment
|
||||||
import androidx.compose.ui.Modifier
|
import androidx.compose.ui.Modifier
|
||||||
|
import androidx.compose.ui.composed
|
||||||
import androidx.compose.ui.draw.clip
|
import androidx.compose.ui.draw.clip
|
||||||
import androidx.compose.ui.draw.shadow
|
import androidx.compose.ui.draw.shadow
|
||||||
import androidx.compose.ui.graphics.Color
|
import androidx.compose.ui.graphics.Color
|
||||||
|
import androidx.compose.ui.graphics.vector.ImageVector
|
||||||
import androidx.compose.ui.input.nestedscroll.nestedScroll
|
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.res.stringResource
|
||||||
import androidx.compose.ui.text.style.TextOverflow
|
|
||||||
import androidx.compose.ui.tooling.preview.Preview
|
import androidx.compose.ui.tooling.preview.Preview
|
||||||
import androidx.compose.ui.unit.dp
|
import androidx.compose.ui.unit.dp
|
||||||
|
import androidx.core.content.edit
|
||||||
import androidx.core.content.pm.PackageInfoCompat
|
import androidx.core.content.pm.PackageInfoCompat
|
||||||
import com.ramcosta.composedestinations.annotation.Destination
|
import com.ramcosta.composedestinations.annotation.Destination
|
||||||
import com.ramcosta.composedestinations.annotation.RootGraph
|
import com.ramcosta.composedestinations.annotation.RootGraph
|
||||||
import com.ramcosta.composedestinations.generated.destinations.InstallScreenDestination
|
import com.ramcosta.composedestinations.generated.destinations.InstallScreenDestination
|
||||||
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
|
import com.ramcosta.composedestinations.navigation.DestinationsNavigator
|
||||||
import kotlinx.coroutines.Dispatchers
|
import com.sukisu.ultra.KernelVersion
|
||||||
import kotlinx.coroutines.withContext
|
import com.sukisu.ultra.Natives
|
||||||
import com.sukisu.ultra.*
|
|
||||||
import com.sukisu.ultra.R
|
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.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 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.BufferedReader
|
||||||
import java.io.InputStreamReader
|
import java.io.InputStreamReader
|
||||||
import java.util.zip.GZIPInputStream
|
import java.util.zip.GZIPInputStream
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
|
|
||||||
@OptIn(ExperimentalMaterial3Api::class)
|
@OptIn(ExperimentalMaterial3Api::class, FlowPreview::class)
|
||||||
@Destination<RootGraph>(start = true)
|
@Destination<RootGraph>(start = true)
|
||||||
@Composable
|
@Composable
|
||||||
fun HomeScreen(navigator: DestinationsNavigator) {
|
fun HomeScreen(navigator: DestinationsNavigator) {
|
||||||
@@ -89,7 +152,7 @@ fun HomeScreen(navigator: DestinationsNavigator) {
|
|||||||
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior(rememberTopAppBarState())
|
val scrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior(rememberTopAppBarState())
|
||||||
|
|
||||||
val isManager = Natives.becomeManager(ksuApp.packageName)
|
val isManager = Natives.becomeManager(ksuApp.packageName)
|
||||||
val deviceModel = getDeviceModel(context)
|
val deviceModel = getDeviceModel()
|
||||||
val ksuVersion = if (isManager) Natives.version else null
|
val ksuVersion = if (isManager) Natives.version else null
|
||||||
val zako = "一.*加.*A.*c.*e.*5.*P.*r.*o".toRegex().matches(deviceModel)
|
val zako = "一.*加.*A.*c.*e.*5.*P.*r.*o".toRegex().matches(deviceModel)
|
||||||
val isVersion = ksuVersion == 12777
|
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(
|
Scaffold(
|
||||||
topBar = {
|
topBar = {
|
||||||
TopBar(
|
TopBar(
|
||||||
@@ -121,10 +188,9 @@ fun HomeScreen(navigator: DestinationsNavigator) {
|
|||||||
Column(
|
Column(
|
||||||
modifier = Modifier
|
modifier = Modifier
|
||||||
.padding(innerPadding)
|
.padding(innerPadding)
|
||||||
.graphicsLayer(clip = true)
|
|
||||||
.disableOverscroll()
|
.disableOverscroll()
|
||||||
.nestedScroll(scrollBehavior.nestedScrollConnection)
|
.nestedScroll(scrollBehavior.nestedScrollConnection)
|
||||||
.verticalScroll(rememberScrollState())
|
.verticalScroll(scrollState)
|
||||||
.padding(top = 12.dp)
|
.padding(top = 12.dp)
|
||||||
.padding(horizontal = 16.dp),
|
.padding(horizontal = 16.dp),
|
||||||
verticalArrangement = Arrangement.spacedBy(12.dp)
|
verticalArrangement = Arrangement.spacedBy(12.dp)
|
||||||
@@ -221,6 +287,21 @@ fun HomeScreen(navigator: DestinationsNavigator) {
|
|||||||
Spacer(Modifier.height(16.dp))
|
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
|
@Composable
|
||||||
@@ -761,9 +842,7 @@ private fun InfoCard() {
|
|||||||
fun InfoCardItem(
|
fun InfoCardItem(
|
||||||
label: String,
|
label: String,
|
||||||
content: String,
|
content: String,
|
||||||
icon: ImageVector = Icons.Default.Info,
|
icon: ImageVector = Icons.Default.Info
|
||||||
maxLines: Int = 2,
|
|
||||||
overflow: TextOverflow = TextOverflow.Ellipsis
|
|
||||||
) {
|
) {
|
||||||
contents.appendLine(label).appendLine(content).appendLine()
|
contents.appendLine(label).appendLine(content).appendLine()
|
||||||
Row(
|
Row(
|
||||||
@@ -814,7 +893,7 @@ private fun InfoCard() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
val deviceModel = getDeviceModel(context)
|
val deviceModel = getDeviceModel()
|
||||||
InfoCardItem(
|
InfoCardItem(
|
||||||
stringResource(R.string.home_device_model),
|
stringResource(R.string.home_device_model),
|
||||||
deviceModel,
|
deviceModel,
|
||||||
@@ -853,9 +932,7 @@ private fun InfoCard() {
|
|||||||
InfoCardItem(
|
InfoCardItem(
|
||||||
stringResource(R.string.home_kpm_version),
|
stringResource(R.string.home_kpm_version),
|
||||||
displayVersion,
|
displayVersion,
|
||||||
icon = Icons.Default.Code,
|
icon = Icons.Default.Code
|
||||||
Int.MAX_VALUE,
|
|
||||||
TextOverflow.Clip
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -883,9 +960,7 @@ private fun InfoCard() {
|
|||||||
InfoCardItem(
|
InfoCardItem(
|
||||||
stringResource(R.string.home_susfs_version),
|
stringResource(R.string.home_susfs_version),
|
||||||
infoText,
|
infoText,
|
||||||
icon = Icons.Default.Storage,
|
icon = Icons.Default.Storage
|
||||||
Int.MAX_VALUE,
|
|
||||||
TextOverflow.Clip
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -924,7 +999,7 @@ private fun WarningCardPreview() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@SuppressLint("PrivateApi")
|
@SuppressLint("PrivateApi")
|
||||||
private fun getDeviceModel(context: Context): String {
|
private fun getDeviceModel(): String {
|
||||||
return try {
|
return try {
|
||||||
val systemProperties = Class.forName("android.os.SystemProperties")
|
val systemProperties = Class.forName("android.os.SystemProperties")
|
||||||
val getMethod = systemProperties.getMethod("get", String::class.java, String::class.java)
|
val getMethod = systemProperties.getMethod("get", String::class.java, String::class.java)
|
||||||
|
|||||||
Reference in New Issue
Block a user