From 7b3e732404618fc3ee8940c20d1bd621cf57d332 Mon Sep 17 00:00:00 2001 From: Light_summer <93428659+lightsummer233@users.noreply.github.com> Date: Sat, 19 Oct 2024 08:40:02 +0800 Subject: [PATCH] manager: Bump dependencies, Adjust pull refresh UI, Add transitions back (#2139) Bump dependencies | Add transitions back for predictive back | Fix SnackBar overlap on FAB & Make SnackBar can dismiss | :-- | :-- | | ![Screenshot_20241016-235706](https://github.com/user-attachments/assets/f2718523-9800-42ff-ad2f-ad8583c56be7) | ![Screenshot_20241018-220552](https://github.com/user-attachments/assets/ed53338b-1ac4-4d0a-a5fb-7056f81cac18) | Use `androidx.compose.material3.pulltorefresh.PullToRefreshBox` instead of `androidx.compose.material.pullrefresh.*` | Before | After | | --: | --: | | ![Screenshot_20241016-234930](https://github.com/user-attachments/assets/6b9dbb87-627b-4a02-8f77-9f9f81ae1b4a) | ![Screenshot_20241016-235336](https://github.com/user-attachments/assets/9134dde4-93c8-4f85-8540-56a7c5a1b0af) | --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> --- .../me/weishu/kernelsu/ui/MainActivity.kt | 22 ++++++-- .../weishu/kernelsu/ui/screen/AppProfile.kt | 12 ++-- .../me/weishu/kernelsu/ui/screen/Flash.kt | 2 + .../me/weishu/kernelsu/ui/screen/Module.kt | 55 ++++++++++--------- .../me/weishu/kernelsu/ui/screen/SuperUser.kt | 26 +++------ .../me/weishu/kernelsu/ui/screen/Template.kt | 28 +++------- manager/gradle/libs.versions.toml | 16 +++--- 7 files changed, 80 insertions(+), 81 deletions(-) diff --git a/manager/app/src/main/java/me/weishu/kernelsu/ui/MainActivity.kt b/manager/app/src/main/java/me/weishu/kernelsu/ui/MainActivity.kt index 2c42c302..0837597e 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/ui/MainActivity.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/ui/MainActivity.kt @@ -5,6 +5,12 @@ import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge +import androidx.compose.animation.AnimatedContentTransitionScope +import androidx.compose.animation.EnterTransition +import androidx.compose.animation.ExitTransition +import androidx.compose.animation.core.tween +import androidx.compose.animation.fadeIn +import androidx.compose.animation.fadeOut import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.WindowInsetsSides import androidx.compose.foundation.layout.displayCutout @@ -16,7 +22,6 @@ import androidx.compose.material3.Icon import androidx.compose.material3.NavigationBar import androidx.compose.material3.NavigationBarItem import androidx.compose.material3.Scaffold -import androidx.compose.material3.SnackbarHost import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -26,9 +31,11 @@ import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp +import androidx.navigation.NavBackStackEntry import androidx.navigation.NavHostController import androidx.navigation.compose.rememberNavController import com.ramcosta.composedestinations.DestinationsNavHost +import com.ramcosta.composedestinations.animations.NavHostAnimatedDestinationStyle import com.ramcosta.composedestinations.generated.NavGraphs import com.ramcosta.composedestinations.utils.isRouteOnBackStackAsState import com.ramcosta.composedestinations.utils.rememberDestinationsNavigator @@ -54,19 +61,24 @@ class MainActivity : ComponentActivity() { setContent { KernelSUTheme { val navController = rememberNavController() - val snackbarHostState = remember { SnackbarHostState() } + val snackBarHostState = remember { SnackbarHostState() } Scaffold( bottomBar = { BottomBar(navController) }, - snackbarHost = { SnackbarHost(snackbarHostState) }, contentWindowInsets = WindowInsets(0, 0, 0, 0) ) { innerPadding -> CompositionLocalProvider( - LocalSnackbarHost provides snackbarHostState, + LocalSnackbarHost provides snackBarHostState, ) { DestinationsNavHost( modifier = Modifier.padding(innerPadding), navGraph = NavGraphs.root, - navController = navController + navController = navController, + defaultTransitions = object : NavHostAnimatedDestinationStyle() { + override val enterTransition: AnimatedContentTransitionScope.() -> EnterTransition + get() = { fadeIn(animationSpec = tween(340)) } + override val exitTransition: AnimatedContentTransitionScope.() -> ExitTransition + get() = { fadeOut(animationSpec = tween(340)) } + } ) } } diff --git a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/AppProfile.kt b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/AppProfile.kt index 502e935e..a9976700 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/AppProfile.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/AppProfile.kt @@ -32,6 +32,7 @@ import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.ListItem import androidx.compose.material3.Scaffold +import androidx.compose.material3.SnackbarHost import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBarDefaults @@ -89,7 +90,7 @@ fun AppProfileScreen( appInfo: SuperUserViewModel.AppInfo, ) { val context = LocalContext.current - val snackbarHost = LocalSnackbarHost.current + val snackBarHost = LocalSnackbarHost.current val scrollBehavior = TopAppBarDefaults.pinnedScrollBehavior() val scope = rememberCoroutineScope() val failToUpdateAppProfile = stringResource(R.string.failed_to_update_app_profile).format(appInfo.label) @@ -111,6 +112,7 @@ fun AppProfileScreen( scrollBehavior = scrollBehavior ) }, + snackbarHost = { SnackbarHost(hostState = snackBarHost) }, contentWindowInsets = WindowInsets.safeDrawing.only(WindowInsetsSides.Top + WindowInsetsSides.Horizontal) ) { paddingValues -> AppProfileInner( @@ -143,12 +145,12 @@ fun AppProfileScreen( scope.launch { if (it.allowSu && !it.rootUseDefault && it.rules.isNotEmpty()) { if (!setSepolicy(profile.name, it.rules)) { - snackbarHost.showSnackbar(failToUpdateSepolicy) + snackBarHost.showSnackbar(failToUpdateSepolicy) return@launch } } if (!Natives.setAppProfile(it)) { - snackbarHost.showSnackbar(failToUpdateAppProfile.format(appInfo.uid)) + snackBarHost.showSnackbar(failToUpdateAppProfile.format(appInfo.uid)) } else { profile = it } @@ -188,7 +190,9 @@ private fun AppProfileInner( ) Crossfade(targetState = isRootGranted, label = "") { current -> - Column { + Column( + modifier = Modifier.padding(bottom = 6.dp + 48.dp + 6.dp /* SnackBar height */) + ) { if (current) { val initialMode = if (profile.rootUseDefault) { Mode.Default diff --git a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Flash.kt b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Flash.kt index af89b03c..a60767d0 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Flash.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Flash.kt @@ -22,6 +22,7 @@ import androidx.compose.material3.Icon import androidx.compose.material3.IconButton import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold +import androidx.compose.material3.SnackbarHost import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBarDefaults @@ -152,6 +153,7 @@ fun FlashScreen(navigator: DestinationsNavigator, flashIt: FlashIt) { ) } }, + snackbarHost = { SnackbarHost(hostState = snackBarHost) }, contentWindowInsets = WindowInsets.safeDrawing.only(WindowInsetsSides.Top + WindowInsetsSides.Horizontal) ) { innerPadding -> KeyEventBlocker { diff --git a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Module.kt b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Module.kt index 11b6d367..f30e8f22 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Module.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Module.kt @@ -1,6 +1,7 @@ package me.weishu.kernelsu.ui.screen import android.app.Activity.RESULT_OK +import android.content.Context import android.content.Intent import android.net.Uri import android.util.Log @@ -31,9 +32,6 @@ import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.Add -import androidx.compose.material.pullrefresh.PullRefreshIndicator -import androidx.compose.material.pullrefresh.pullRefresh -import androidx.compose.material.pullrefresh.rememberPullRefreshState import androidx.compose.material3.Button import androidx.compose.material3.ElevatedCard import androidx.compose.material3.ExperimentalMaterial3Api @@ -42,6 +40,9 @@ import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.Icon import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Scaffold +import androidx.compose.material3.SnackbarDuration +import androidx.compose.material3.SnackbarHost +import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.SnackbarResult import androidx.compose.material3.Switch import androidx.compose.material3.Text @@ -49,6 +50,7 @@ import androidx.compose.material3.TextButton import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBarDefaults import androidx.compose.material3.TopAppBarScrollBehavior +import androidx.compose.material3.pulltorefresh.PullToRefreshBox import androidx.compose.material3.rememberTopAppBarState import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect @@ -102,6 +104,7 @@ import okhttp3.OkHttpClient fun ModuleScreen(navigator: DestinationsNavigator) { val viewModel = viewModel() val context = LocalContext.current + val snackBarHost = LocalSnackbarHost.current LaunchedEffect(Unit) { if (viewModel.moduleList.isEmpty() || viewModel.isNeedRefresh) { @@ -154,7 +157,8 @@ fun ModuleScreen(navigator: DestinationsNavigator) { } }, - contentWindowInsets = WindowInsets.safeDrawing.only(WindowInsetsSides.Top + WindowInsetsSides.Horizontal) + contentWindowInsets = WindowInsets.safeDrawing.only(WindowInsetsSides.Top + WindowInsetsSides.Horizontal), + snackbarHost = { SnackbarHost(hostState = snackBarHost) } ) { innerPadding -> when { hasMagisk -> { @@ -187,21 +191,25 @@ fun ModuleScreen(navigator: DestinationsNavigator) { .putExtra("name", name) ) } - } + }, + context = context, + snackBarHost = snackBarHost ) } } } } -@OptIn(ExperimentalMaterialApi::class) +@OptIn(ExperimentalMaterialApi::class, ExperimentalMaterial3Api::class) @Composable private fun ModuleList( viewModel: ModuleViewModel, modifier: Modifier = Modifier, boxModifier: Modifier = Modifier, onInstallModule: (Uri) -> Unit, - onClickModule: (id: String, name: String, hasWebUi: Boolean) -> Unit + onClickModule: (id: String, name: String, hasWebUi: Boolean) -> Unit, + context: Context, + snackBarHost: SnackbarHostState ) { val failedEnable = stringResource(R.string.module_failed_to_enable) val failedDisable = stringResource(R.string.module_failed_to_disable) @@ -219,9 +227,6 @@ private fun ModuleList( val startDownloadingText = stringResource(R.string.module_start_downloading) val fetchChangeLogFailed = stringResource(R.string.module_changelog_failed) - val snackBarHost = LocalSnackbarHost.current - val context = LocalContext.current - val loadingDialog = rememberLoadingDialog() val confirmDialog = rememberConfirmDialog() @@ -320,18 +325,21 @@ private fun ModuleList( } else { null } - val result = snackBarHost.showSnackbar(message, actionLabel = actionLabel) + val result = snackBarHost.showSnackbar( + message = message, + actionLabel = actionLabel, + duration = SnackbarDuration.Long + ) if (result == SnackbarResult.ActionPerformed) { reboot() } } - - val refreshState = rememberPullRefreshState( - refreshing = viewModel.isRefreshing, - onRefresh = { viewModel.fetchModuleList() } - ) - Box( - boxModifier.pullRefresh(refreshState) + PullToRefreshBox( + modifier = boxModifier, + onRefresh = { + viewModel.fetchModuleList() + }, + isRefreshing = viewModel.isRefreshing ) { LazyColumn( modifier = modifier, @@ -341,7 +349,7 @@ private fun ModuleList( start = 16.dp, top = 16.dp, end = 16.dp, - bottom = 16.dp + 16.dp + 56.dp /* Scaffold Fab Spacing + Fab container height */ + bottom = 16.dp + 56.dp + 16.dp + 48.dp + 6.dp /* Scaffold Fab Spacing + Fab container height + SnackBar height */ ) }, ) { @@ -398,7 +406,9 @@ private fun ModuleList( viewModel.fetchModuleList() val result = snackBarHost.showSnackbar( - rebootToApply, actionLabel = reboot + message = rebootToApply, + actionLabel = reboot, + duration = SnackbarDuration.Long ) if (result == SnackbarResult.ActionPerformed) { reboot() @@ -430,11 +440,6 @@ private fun ModuleList( DownloadListener(context, onInstallModule) - PullRefreshIndicator( - refreshing = viewModel.isRefreshing, state = refreshState, modifier = Modifier.align( - Alignment.TopCenter - ) - ) } } diff --git a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/SuperUser.kt b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/SuperUser.kt index 14f2aad1..1a37d011 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/SuperUser.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/SuperUser.kt @@ -9,12 +9,9 @@ import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.MoreVert -import androidx.compose.material.pullrefresh.PullRefreshIndicator -import androidx.compose.material.pullrefresh.pullRefresh -import androidx.compose.material.pullrefresh.rememberPullRefreshState import androidx.compose.material3.* +import androidx.compose.material3.pulltorefresh.PullToRefreshBox import androidx.compose.runtime.* -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.graphics.Color import androidx.compose.ui.input.nestedscroll.nestedScroll @@ -99,14 +96,12 @@ fun SuperUserScreen(navigator: DestinationsNavigator) { }, contentWindowInsets = WindowInsets.safeDrawing.only(WindowInsetsSides.Top + WindowInsetsSides.Horizontal) ) { innerPadding -> - val refreshState = rememberPullRefreshState( - refreshing = viewModel.isRefreshing, - onRefresh = { scope.launch { viewModel.fetchAppList() } }, - ) - Box( - modifier = Modifier - .padding(innerPadding) - .pullRefresh(refreshState) + PullToRefreshBox( + modifier = Modifier.padding(innerPadding), + onRefresh = { + scope.launch { viewModel.fetchAppList() } + }, + isRefreshing = viewModel.isRefreshing ) { LazyColumn( modifier = Modifier @@ -117,15 +112,8 @@ fun SuperUserScreen(navigator: DestinationsNavigator) { AppItem(app) { navigator.navigate(AppProfileScreenDestination(app)) } - } } - - PullRefreshIndicator( - refreshing = viewModel.isRefreshing, - state = refreshState, - modifier = Modifier.align(Alignment.TopCenter) - ) } } } diff --git a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Template.kt b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Template.kt index 33bbcd6a..3074f4e1 100644 --- a/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Template.kt +++ b/manager/app/src/main/java/me/weishu/kernelsu/ui/screen/Template.kt @@ -2,7 +2,6 @@ package me.weishu.kernelsu.ui.screen import android.widget.Toast import androidx.compose.foundation.clickable -import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.ExperimentalLayoutApi import androidx.compose.foundation.layout.FlowRow @@ -21,9 +20,6 @@ import androidx.compose.material.icons.automirrored.filled.ArrowBack import androidx.compose.material.icons.filled.Add import androidx.compose.material.icons.filled.ImportExport import androidx.compose.material.icons.filled.Sync -import androidx.compose.material.pullrefresh.PullRefreshIndicator -import androidx.compose.material.pullrefresh.pullRefresh -import androidx.compose.material.pullrefresh.rememberPullRefreshState import androidx.compose.material3.DropdownMenu import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.ExperimentalMaterial3Api @@ -37,6 +33,7 @@ import androidx.compose.material3.Text import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBarDefaults import androidx.compose.material3.TopAppBarScrollBehavior +import androidx.compose.material3.pulltorefresh.PullToRefreshBox import androidx.compose.material3.rememberTopAppBarState import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect @@ -45,7 +42,6 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue -import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.input.nestedscroll.nestedScroll import androidx.compose.ui.platform.LocalClipboardManager @@ -155,33 +151,25 @@ fun AppProfileTemplateScreen( }, contentWindowInsets = WindowInsets.safeDrawing.only(WindowInsetsSides.Top + WindowInsetsSides.Horizontal) ) { innerPadding -> - val refreshState = rememberPullRefreshState( - refreshing = viewModel.isRefreshing, - onRefresh = { scope.launch { viewModel.fetchTemplates() } }, - ) - Box( - modifier = Modifier - .padding(innerPadding) - .pullRefresh(refreshState) + PullToRefreshBox( + modifier = Modifier.padding(innerPadding), + isRefreshing = viewModel.isRefreshing, + onRefresh = { + scope.launch { viewModel.fetchTemplates() } + } ) { LazyColumn( modifier = Modifier .fillMaxSize() .nestedScroll(scrollBehavior.nestedScrollConnection), contentPadding = remember { - PaddingValues(bottom = 16.dp + 16.dp + 56.dp /* Scaffold Fab Spacing + Fab container height */) + PaddingValues(bottom = 16.dp + 56.dp + 16.dp /* Scaffold Fab Spacing + Fab container height */) } ) { items(viewModel.templateList, key = { it.id }) { app -> TemplateItem(navigator, app) } } - - PullRefreshIndicator( - refreshing = viewModel.isRefreshing, - state = refreshState, - modifier = Modifier.align(Alignment.TopCenter) - ) } } } diff --git a/manager/gradle/libs.versions.toml b/manager/gradle/libs.versions.toml index 7492e81c..e739e139 100644 --- a/manager/gradle/libs.versions.toml +++ b/manager/gradle/libs.versions.toml @@ -1,17 +1,17 @@ [versions] -agp = "8.6.1" -kotlin = "2.0.20" -ksp = "2.0.20-1.0.25" -compose-bom = "2024.09.02" +agp = "8.7.1" +kotlin = "2.0.21" +ksp = "2.0.21-1.0.25" +compose-bom = "2024.10.00" lifecycle = "2.8.6" -navigation = "2.8.1" -activity-compose = "1.9.2" +navigation = "2.8.3" +activity-compose = "1.9.3" kotlinx-coroutines = "1.9.0" coil-compose = "2.7.0" -compose-destination = "2.1.0-beta12" +compose-destination = "2.1.0-beta13" sheets-compose-dialogs = "1.3.0" markdown = "4.6.2" -webkit = "1.12.0" +webkit = "1.12.1" appiconloader-coil = "1.5.0" parcelablelist = "2.0.1" libsu = "6.0.0"