From b633ce5ed693bf82d2c3d714809c4ca8f308bcf9 Mon Sep 17 00:00:00 2001 From: Timofei Pushkin Date: Sun, 2 Feb 2025 18:20:38 +0100 Subject: [PATCH] Update dependencies --- .../java/ru/spbu/depnav/ui/MainActivity.kt | 31 ++-- .../spbu/depnav/ui/component/MapSearchBar.kt | 135 +++++++++--------- .../ru/spbu/depnav/ui/screen/MapScreen.kt | 12 +- gradle/libs.versions.toml | 18 +-- gradle/wrapper/gradle-wrapper.properties | 4 +- 5 files changed, 92 insertions(+), 108 deletions(-) diff --git a/app/src/main/java/ru/spbu/depnav/ui/MainActivity.kt b/app/src/main/java/ru/spbu/depnav/ui/MainActivity.kt index aad764cf..70c89dc4 100644 --- a/app/src/main/java/ru/spbu/depnav/ui/MainActivity.kt +++ b/app/src/main/java/ru/spbu/depnav/ui/MainActivity.kt @@ -25,7 +25,6 @@ import androidx.activity.SystemBarStyle import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import androidx.compose.foundation.isSystemInDarkTheme -import androidx.compose.runtime.CompositionLocalProvider import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.lifecycle.compose.collectAsStateWithLifecycle @@ -47,27 +46,19 @@ class MainActivity : ComponentActivity() { super.onCreate(savedInstanceState) setContent { - CompositionLocalProvider( - // Fix for https://issuetracker.google.com/issues/336842920 -- should be removed as - // soon as Compose UI 1.7.0 becomes stable - androidx.lifecycle.compose.LocalLifecycleOwner provides - androidx.compose.ui.platform.LocalLifecycleOwner.current - ) { - val themeMode by prefs.themeModeFlow.collectAsStateWithLifecycle() - val darkTheme = when (themeMode) { - ThemeMode.LIGHT -> false - ThemeMode.DARK -> true - ThemeMode.SYSTEM -> isSystemInDarkTheme() - } - - LaunchedEffect(darkTheme) { - val style = - SystemBarStyle.auto(Color.TRANSPARENT, Color.TRANSPARENT) { darkTheme } - enableEdgeToEdge(style, style) - } + val themeMode by prefs.themeModeFlow.collectAsStateWithLifecycle() + val darkTheme = when (themeMode) { + ThemeMode.LIGHT -> false + ThemeMode.DARK -> true + ThemeMode.SYSTEM -> isSystemInDarkTheme() + } - DepNavTheme(darkTheme = darkTheme) { MapScreen(prefs) } + LaunchedEffect(darkTheme) { + val style = SystemBarStyle.auto(Color.TRANSPARENT, Color.TRANSPARENT) { darkTheme } + enableEdgeToEdge(style, style) } + + DepNavTheme(darkTheme = darkTheme) { MapScreen(prefs) } } } } diff --git a/app/src/main/java/ru/spbu/depnav/ui/component/MapSearchBar.kt b/app/src/main/java/ru/spbu/depnav/ui/component/MapSearchBar.kt index e15aee0d..2d803920 100644 --- a/app/src/main/java/ru/spbu/depnav/ui/component/MapSearchBar.kt +++ b/app/src/main/java/ru/spbu/depnav/ui/component/MapSearchBar.kt @@ -29,8 +29,6 @@ import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.WindowInsets import androidx.compose.foundation.layout.WindowInsetsSides import androidx.compose.foundation.layout.asPaddingValues -import androidx.compose.foundation.layout.calculateEndPadding -import androidx.compose.foundation.layout.calculateStartPadding import androidx.compose.foundation.layout.only import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.safeDrawing @@ -50,23 +48,25 @@ import androidx.compose.material3.minimumInteractiveComponentSize import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalDensity import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.platform.LocalLayoutDirection import androidx.compose.ui.platform.LocalSoftwareKeyboardController import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextOverflow +import androidx.compose.ui.util.lerp import ru.spbu.depnav.R import ru.spbu.depnav.ui.theme.DEFAULT_PADDING import ru.spbu.depnav.ui.theme.ON_MAP_SURFACE_ALPHA import ru.spbu.depnav.ui.viewmodel.SearchResults // These are basically copied from SearchBar implementation -private val ACTIVATION_ENTER_SPEC = tween( +private val EXPANSION_ENTER_SPEC = tween( durationMillis = 600, delayMillis = 100, easing = CubicBezierEasing(0.05f, 0.7f, 0.1f, 1.0f) ) -private val ACTIVATION_EXIT_SPEC = tween( +private val EXPANSION_EXIT_SPEC = tween( durationMillis = 350, delayMillis = 100, easing = CubicBezierEasing(0.0f, 1.0f, 0.0f, 1.0f) @@ -76,81 +76,59 @@ private val ACTIVATION_EXIT_SPEC = tween( * Search bar for querying map markers on [ru.spbu.depnav.ui.screen.MapScreen]. */ @Composable -@Suppress( - "LongMethod", // No point in further shrinking - "LongParameterList" // Considered OK for a composable -) +@Suppress("LongParameterList") // Considered OK for a composable @OptIn(ExperimentalMaterial3Api::class) fun MapSearchBar( query: String, onQueryChange: (String) -> Unit, mapTitle: String, - active: Boolean, - onActiveChange: (Boolean) -> Unit, + expanded: Boolean, + onExpandedChange: (Boolean) -> Unit, results: SearchResults, onResultClick: (Int) -> Unit, onMenuClick: () -> Unit, modifier: Modifier = Modifier ) { - val activationAnimationProgress by animateFloatAsState( - targetValue = if (active) 1f else 0f, - animationSpec = if (active) ACTIVATION_ENTER_SPEC else ACTIVATION_EXIT_SPEC, - label = "Map search bar activation animation progress" + val expansionAnimationProgress by animateFloatAsState( + targetValue = if (expanded) 1f else 0f, + animationSpec = if (expanded) EXPANSION_ENTER_SPEC else EXPANSION_EXIT_SPEC, + label = "Map search bar expansion animation progress" ) - val (insetsStartPadding, insetsEndPadding) = with(WindowInsets.safeDrawing.asPaddingValues()) { - val layoutDirection = LocalLayoutDirection.current - calculateStartPadding(layoutDirection) to calculateEndPadding(layoutDirection) - } - - val outerStartPadding = insetsStartPadding * (1 - activationAnimationProgress) - val outerEndPadding = insetsEndPadding * (1 - activationAnimationProgress) - val innerStartPadding = insetsStartPadding * activationAnimationProgress - val innerEndPadding = insetsEndPadding * activationAnimationProgress - - val focusManager = LocalFocusManager.current - - val containerColorAlpha = - ON_MAP_SURFACE_ALPHA + (1 - ON_MAP_SURFACE_ALPHA) * activationAnimationProgress - SearchBar( - query = query, - onQueryChange = onQueryChange, - onSearch = { focusManager.clearFocus() }, - active = active, - onActiveChange = onActiveChange, - modifier = Modifier - .run { - if (active) padding(start = outerStartPadding, end = outerEndPadding) - else windowInsetsPadding(WindowInsets.safeDrawing.only(WindowInsetsSides.Horizontal)) - } - .then(modifier), - placeholder = { - Text( - stringResource(R.string.search_on_map, mapTitle), - overflow = TextOverflow.Ellipsis, - maxLines = 1 - ) - }, - leadingIcon = { - AnimatedLeadingIcon( - active, - onMenuClick = onMenuClick, - modifier = Modifier.padding(start = innerStartPadding), - onNavigateBackClick = { onActiveChange(false) } - ) - }, - trailingIcon = { - AnimatedTrailingIcon( - active, - query.isEmpty(), - onClearClick = { onQueryChange("") }, - modifier = Modifier.padding(end = innerEndPadding) - ) + inputField = { + SearchBarDefaults.InputField( + query = query, + onQueryChange = onQueryChange, + onSearch = with(LocalFocusManager.current) { { clearFocus() } }, + expanded = expanded, + onExpandedChange = onExpandedChange, + modifier = Modifier.windowInsetsPadding( + WindowInsets.safeDrawing.only(WindowInsetsSides.Horizontal) * + expansionAnimationProgress + ), + placeholder = { Placeholder(mapTitle) }, + leadingIcon = { + AnimatedLeadingIcon( + expanded, + onMenuClick = onMenuClick, + onNavigateBackClick = { onExpandedChange(false) } + ) + }, + trailingIcon = { + AnimatedTrailingIcon( + expanded, + query.isEmpty(), + onClearClick = { onQueryChange("") } + ) + }) }, + expanded = expanded, + onExpandedChange = onExpandedChange, + modifier = modifier, colors = SearchBarDefaults.colors( containerColor = MaterialTheme.colorScheme.surfaceVariant.copy( - alpha = containerColorAlpha + alpha = lerp(ON_MAP_SURFACE_ALPHA, 1f, expansionAnimationProgress) ) ) ) { @@ -160,22 +138,37 @@ fun MapSearchBar( results, onScroll = { onTop -> keyboard?.apply { if (onTop) show() else hide() } }, onResultClick = { - onActiveChange(false) + onExpandedChange(false) onResultClick(it) }, modifier = Modifier + .windowInsetsPadding(WindowInsets.safeDrawing) .padding(horizontal = DEFAULT_PADDING * 1.5f) - .padding( - start = innerStartPadding, - end = innerEndPadding, - bottom = WindowInsets.safeDrawing - .asPaddingValues() - .calculateBottomPadding() - ) ) } } +@Composable +private operator fun WindowInsets.times(num: Float): WindowInsets { + val paddings = asPaddingValues(LocalDensity.current) + val layoutDirection = LocalLayoutDirection.current + return WindowInsets( + paddings.calculateLeftPadding(layoutDirection) * num, + paddings.calculateTopPadding() * num, + paddings.calculateRightPadding(layoutDirection) * num, + paddings.calculateBottomPadding() * num + ) +} + +@Composable +private fun Placeholder(mapTitle: String) { + Text( + stringResource(R.string.search_on_map, mapTitle), + overflow = TextOverflow.Ellipsis, + maxLines = 1 + ) +} + @Composable private fun AnimatedLeadingIcon( searchBarActive: Boolean, diff --git a/app/src/main/java/ru/spbu/depnav/ui/screen/MapScreen.kt b/app/src/main/java/ru/spbu/depnav/ui/screen/MapScreen.kt index 117dbbb4..0c17a1d5 100644 --- a/app/src/main/java/ru/spbu/depnav/ui/screen/MapScreen.kt +++ b/app/src/main/java/ru/spbu/depnav/ui/screen/MapScreen.kt @@ -218,12 +218,12 @@ private fun BoxScope.AnimatedSearchBar( onResultClick: (Int) -> Unit, onMenuClick: () -> Unit ) { - var searchBarActive by rememberSaveable { mutableStateOf(false) } + var searchBarExpanded by rememberSaveable { mutableStateOf(false) } if (!visible) { - searchBarActive = false + searchBarExpanded = false } - if (!searchBarActive && query.isNotEmpty()) { + if (!searchBarExpanded && query.isNotEmpty()) { onQueryChange("") } @@ -236,7 +236,7 @@ private fun BoxScope.AnimatedSearchBar( exit = slideOutVertically(targetOffsetY = { -it }) + fadeOut() ) { val horizontalPadding by animateDpAsState( - if (searchBarActive) 0.dp else DEFAULT_PADDING, + if (searchBarExpanded) 0.dp else DEFAULT_PADDING, label = "Map search bar horizontal padding" ) @@ -244,8 +244,8 @@ private fun BoxScope.AnimatedSearchBar( query = query, onQueryChange = onQueryChange, mapTitle = mapTitle, - active = searchBarActive, - onActiveChange = { searchBarActive = it }, + expanded = searchBarExpanded, + onExpandedChange = { searchBarExpanded = it }, results = searchResults, onResultClick = onResultClick, onMenuClick = onMenuClick, diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 4f2a82a2..2dcf5735 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -1,9 +1,9 @@ [versions] -kotlin = "2.0.20" -kspPlugin = "2.0.20-1.0.24" -hilt = "2.52" -lifecycle = "2.8.4" +kotlin = "2.1.10" +kspPlugin = "2.1.10-1.0.29" +hilt = "2.55" +lifecycle = "2.8.7" room = "2.6.1" @@ -20,15 +20,15 @@ androidx-room-compiler = { group = "androidx.room", name = "room-compiler", vers google-dagger-hilt = { group = "com.google.dagger", name = "hilt-android", version.ref = "hilt" } google-dagger-hiltCompiler = { group = "com.google.dagger", name = "hilt-compiler", version.ref = "hilt" } -androidx-compose-bom = "androidx.compose:compose-bom:2024.08.00" +androidx-compose-bom = "androidx.compose:compose-bom:2025.01.01" androidx-compose-material3 = { module = "androidx.compose.material3:material3" } androidx-compose-ui = { module = "androidx.compose.ui:ui" } androidx-compose-ui-tooling = { module = "androidx.compose.ui:ui-tooling" } androidx-compose-ui-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview" } -androidx-core-ktx = "androidx.core:core-ktx:1.13.1" -androidx-activity-compose = "androidx.activity:activity-compose:1.9.1" -plrapps-mapcompose = "ovh.plrapps:mapcompose:2.12.6" +androidx-core-ktx = "androidx.core:core-ktx:1.15.0" +androidx-activity-compose = "androidx.activity:activity-compose:1.10.0" +plrapps-mapcompose = "ovh.plrapps:mapcompose:2.14.0" junit = "junit:junit:4.13.2" androidx-test-runner = "androidx.test:runner:1.6.2" @@ -38,7 +38,7 @@ androidx-test-extJunit = "androidx.test.ext:junit:1.2.1" [plugins] -android-application = { id = "com.android.application", version = "8.5.2" } +android-application = { id = "com.android.application", version = "8.8.0" } jetbrains-kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" } jetbrains-kotlin-plugin-compose = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } google-dagger-hilt-android = { id = "com.google.dagger.hilt.android", version.ref = "hilt" } diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 8ab18bbe..7d00d29e 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ -#Tue Aug 27 22:36:14 CEST 2024 +#Sat Feb 01 19:06:21 CET 2025 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-8.10-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.12.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists