refactor: edgeToEdge tweaks, chip elevation (#1962)

This commit is contained in:
James Rich
2025-05-28 09:34:08 -05:00
committed by GitHub
parent 9f0765526d
commit 3eefe4b66c
9 changed files with 56 additions and 97 deletions

View File

@@ -38,11 +38,10 @@ import androidx.activity.viewModels
import androidx.appcompat.app.AppCompatActivity
import androidx.appcompat.app.AppCompatDelegate
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.safeDrawingPadding
import androidx.compose.runtime.SideEffect
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalView
import androidx.core.content.edit
import androidx.core.net.toUri
import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen
@@ -133,24 +132,31 @@ class MainActivity : AppCompatActivity(), Logging {
}
setContent {
Box(Modifier.safeDrawingPadding()) {
val theme by model.theme.collectAsState()
val dynamic = theme == MODE_DYNAMIC
val dark = when (theme) {
AppCompatDelegate.MODE_NIGHT_YES -> true
AppCompatDelegate.MODE_NIGHT_NO -> false
AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM -> isSystemInDarkTheme()
else -> isSystemInDarkTheme()
}
AppTheme(
dynamicColor = dynamic,
darkTheme = dark,
) {
MainScreen(viewModel = model, onAction = ::onMainMenuAction)
val theme by model.theme.collectAsState()
val dynamic = theme == MODE_DYNAMIC
val dark = when (theme) {
AppCompatDelegate.MODE_NIGHT_YES -> true
AppCompatDelegate.MODE_NIGHT_NO -> false
AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM -> isSystemInDarkTheme()
else -> isSystemInDarkTheme()
}
AppTheme(
dynamicColor = dynamic,
darkTheme = dark,
) {
val view = LocalView.current
if (!view.isInEditMode) {
SideEffect {
AppCompatDelegate.setDefaultNightMode(theme)
}
}
MainScreen(
viewModel = model,
onAction = ::onMainMenuAction
)
}
}
// Handle any intent
handleIntent(intent)
}

View File

@@ -274,8 +274,6 @@ fun NavGraph(
) { backStackEntry ->
SettingsScreen(
uIViewModel,
sharedTransitionScope = this@SharedTransitionLayout,
animatedContentScope = this@composable,
onNavigateToRadioConfig = {
navController.navigate(Route.RadioConfig()) {
popUpTo(Route.Settings) {

View File

@@ -99,6 +99,7 @@ enum class TopLevelDestination(val label: String, val icon: ImageVector, val rou
@Suppress("LongMethod")
@Composable
fun MainScreen(
modifier: Modifier = Modifier,
viewModel: UIViewModel = hiltViewModel(),
onAction: (MainMenuAction) -> Unit
) {
@@ -146,6 +147,7 @@ fun MainScreen(
}
Scaffold(
modifier = modifier,
topBar = {
MainAppBar(
title = title,

View File

@@ -17,9 +17,6 @@
package com.geeksville.mesh.ui
import androidx.compose.animation.AnimatedContentScope
import androidx.compose.animation.ExperimentalSharedTransitionApi
import androidx.compose.animation.SharedTransitionScope
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
@@ -27,8 +24,8 @@ import androidx.compose.foundation.layout.IntrinsicSize
import androidx.compose.foundation.layout.defaultMinSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.width
import androidx.compose.material3.AssistChip
import androidx.compose.material3.AssistChipDefaults
import androidx.compose.material3.ElevatedAssistChip
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
@@ -45,7 +42,6 @@ import com.geeksville.mesh.model.Node
import com.geeksville.mesh.ui.components.NodeMenu
import com.geeksville.mesh.ui.components.NodeMenuAction
@OptIn(ExperimentalSharedTransitionApi::class)
@Composable
fun NodeChip(
modifier: Modifier = Modifier,
@@ -53,43 +49,33 @@ fun NodeChip(
isThisNode: Boolean,
isConnected: Boolean,
onAction: (NodeMenuAction) -> Unit,
sharedTransitionScope: SharedTransitionScope,
animatedContentScope: AnimatedContentScope,
) {
val isIgnored = node.isIgnored
val (textColor, nodeColor) = node.colors
var menuExpanded by remember { mutableStateOf(false) }
val inputChipInteractionSource = remember { MutableInteractionSource() }
Box {
with(sharedTransitionScope) {
ElevatedAssistChip(
modifier = modifier
.width(IntrinsicSize.Min)
.defaultMinSize(minHeight = 32.dp, minWidth = 72.dp)
.sharedElement(
rememberSharedContentState("node_chip_${node.num}"),
animatedContentScope
),
colors = AssistChipDefaults.assistChipColors(
containerColor = Color(nodeColor),
labelColor = Color(textColor),
),
label = {
Text(
modifier = Modifier.Companion.fillMaxWidth().sharedElement(
rememberSharedContentState("node_shortname_${node.num}"),
animatedContentScope
),
text = node.user.shortName.ifEmpty { "???" },
fontSize = MaterialTheme.typography.labelLarge.fontSize,
textDecoration = TextDecoration.Companion.LineThrough.takeIf { isIgnored },
textAlign = TextAlign.Companion.Center,
)
},
onClick = {},
interactionSource = inputChipInteractionSource,
)
}
AssistChip(
modifier = modifier
.width(IntrinsicSize.Min)
.defaultMinSize(minHeight = 32.dp, minWidth = 72.dp),
colors = AssistChipDefaults.assistChipColors(
containerColor = Color(nodeColor),
labelColor = Color(textColor),
),
label = {
Text(
modifier = Modifier.Companion
.fillMaxWidth(),
text = node.user.shortName.ifEmpty { "???" },
fontSize = MaterialTheme.typography.labelLarge.fontSize,
textDecoration = TextDecoration.Companion.LineThrough.takeIf { isIgnored },
textAlign = TextAlign.Companion.Center,
)
},
onClick = {},
interactionSource = inputChipInteractionSource,
)
Box(
modifier = Modifier.Companion
.matchParentSize()

View File

@@ -18,9 +18,7 @@
package com.geeksville.mesh.ui
import android.content.res.Configuration
import androidx.compose.animation.AnimatedContentScope
import androidx.compose.animation.ExperimentalSharedTransitionApi
import androidx.compose.animation.SharedTransitionScope
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
@@ -63,9 +61,9 @@ import com.geeksville.mesh.ui.components.SignalInfo
import com.geeksville.mesh.ui.compose.ElevationInfo
import com.geeksville.mesh.ui.compose.SatelliteCountInfo
import com.geeksville.mesh.ui.preview.NodePreviewParameterProvider
import com.geeksville.mesh.ui.theme.AppTheme
import com.geeksville.mesh.util.toDistanceString
@OptIn(ExperimentalSharedTransitionApi::class)
@Suppress("LongMethod", "CyclomaticComplexMethod")
@Composable
fun NodeItem(
@@ -79,8 +77,6 @@ fun NodeItem(
expanded: Boolean = false,
currentTimeMillis: Long,
isConnected: Boolean = false,
sharedTransitionScope: SharedTransitionScope,
animatedContentScope: AnimatedContentScope,
) {
val isFavorite = remember(thatNode) { thatNode.isFavorite }
val isIgnored = thatNode.isIgnored
@@ -139,8 +135,6 @@ fun NodeItem(
isThisNode = isThisNode,
isConnected = isConnected,
onAction = onAction,
sharedTransitionScope = sharedTransitionScope,
animatedContentScope = animatedContentScope,
)
NodeKeyStatusIcon(
@@ -285,8 +279,6 @@ fun NodeInfoSimplePreview() {
0,
true,
currentTimeMillis = System.currentTimeMillis(),
sharedTransitionScope = sharedTransitionScope,
animatedContentScope = animatedContentScope,
)
}
}
@@ -301,7 +293,7 @@ fun NodeInfoPreview(
@PreviewParameter(NodePreviewParameterProvider::class)
thatNode: Node
) {
SharedTransitionPreview { sharedTransitionScope, animatedContentScope ->
AppTheme {
val thisNode = NodePreviewParameterProvider().values.first()
Column {
Text(
@@ -316,8 +308,6 @@ fun NodeInfoPreview(
tempInFahrenheit = true,
expanded = false,
currentTimeMillis = System.currentTimeMillis(),
sharedTransitionScope = sharedTransitionScope,
animatedContentScope = animatedContentScope,
)
Text(
text = "Details Shown",
@@ -331,8 +321,6 @@ fun NodeInfoPreview(
tempInFahrenheit = true,
expanded = true,
currentTimeMillis = System.currentTimeMillis(),
sharedTransitionScope = sharedTransitionScope,
animatedContentScope = animatedContentScope,
)
}
}

View File

@@ -25,9 +25,6 @@ import android.os.Build
import android.util.Patterns
import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.animation.AnimatedContentScope
import androidx.compose.animation.ExperimentalSharedTransitionApi
import androidx.compose.animation.SharedTransitionScope
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
@@ -109,15 +106,12 @@ fun String?.isIPAddress(): Boolean {
}
}
@OptIn(ExperimentalSharedTransitionApi::class)
@Suppress("CyclomaticComplexMethod", "LongMethod")
@Composable
fun SettingsScreen(
uiViewModel: UIViewModel = hiltViewModel(),
scanModel: BTScanModel = hiltViewModel(),
bluetoothViewModel: BluetoothViewModel = hiltViewModel(),
sharedTransitionScope: SharedTransitionScope,
animatedContentScope: AnimatedContentScope,
onNavigateToRadioConfig: () -> Unit,
onNavigateToNodeDetails: (Int) -> Unit,
) {
@@ -233,6 +227,7 @@ fun SettingsScreen(
}
lastConnection = info
}
else -> {}
}
}
@@ -284,8 +279,6 @@ fun SettingsScreen(
else -> {}
}
},
sharedTransitionScope = sharedTransitionScope,
animatedContentScope = animatedContentScope
)
Spacer(modifier = Modifier.width(8.dp))
Text(

View File

@@ -17,10 +17,7 @@
package com.geeksville.mesh.ui.message.components
import androidx.compose.animation.AnimatedContentScope
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.ExperimentalSharedTransitionApi
import androidx.compose.animation.SharedTransitionScope
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
@@ -58,11 +55,11 @@ import com.geeksville.mesh.model.Node
import com.geeksville.mesh.ui.NodeChip
import com.geeksville.mesh.ui.components.AutoLinkText
import com.geeksville.mesh.ui.components.NodeMenuAction
import com.geeksville.mesh.ui.components.SharedTransitionPreview
import com.geeksville.mesh.ui.preview.NodePreviewParameterProvider
import com.geeksville.mesh.ui.theme.AppTheme
@Suppress("LongMethod", "CyclomaticComplexMethod")
@OptIn(ExperimentalFoundationApi::class, ExperimentalSharedTransitionApi::class)
@OptIn(ExperimentalFoundationApi::class)
@Composable
internal fun MessageItem(
node: Node,
@@ -76,8 +73,6 @@ internal fun MessageItem(
onAction: (NodeMenuAction) -> Unit = {},
onStatusClick: () -> Unit = {},
onSendReaction: (String) -> Unit = {},
sharedTransitionScope: SharedTransitionScope,
animatedContentScope: AnimatedContentScope,
isConnected: Boolean,
) = Row(
modifier = modifier
@@ -105,8 +100,6 @@ internal fun MessageItem(
onAction = onAction,
isConnected = isConnected,
isThisNode = false,
sharedTransitionScope = sharedTransitionScope,
animatedContentScope = animatedContentScope,
)
}
Card(
@@ -177,19 +170,16 @@ internal fun MessageItem(
}
}
@OptIn(ExperimentalSharedTransitionApi::class)
@PreviewLightDark
@Composable
private fun MessageItemPreview() {
SharedTransitionPreview { sharedTransitionScope, animatedContentScope ->
AppTheme {
MessageItem(
node = NodePreviewParameterProvider().values.first(),
messageText = stringResource(R.string.sample_message),
messageTime = "10:00",
messageStatus = MessageStatus.DELIVERED,
selected = false,
sharedTransitionScope = sharedTransitionScope,
animatedContentScope = animatedContentScope,
isConnected = true,
)
}

View File

@@ -18,11 +18,7 @@
<resources>
<!-- Base application theme. -->
<style name="AppTheme" parent="Theme.Material3.DynamicColors.DayNight.NoActionBar">
<!-- Customize your theme here. -->
<item name="android:windowTranslucentStatus">true</item>
<item name="android:windowTranslucentNavigation">true</item>
</style>
<style name="AppTheme" parent="Theme.Material3.DynamicColors.DayNight.NoActionBar"/>
<style name="Theme.App.Starting" parent="Theme.SplashScreen">
// Set the splash screen background, animated icon, and animation duration.

View File

@@ -30,7 +30,7 @@ kotlinx-coroutines-android = "1.10.2"
kotlinx-serialization-json = "1.8.1"
lifecycle = "2.9.0"
material = "1.12.0"
material3 = "1.3.2"
material3 = "1.4.0-alpha15"
mgrs = "2.1.3"
navigation = "2.9.0"
okhttp = "4.12.0"