diff --git a/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/qrcode/ui/QrImageCodeChooser.kt b/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/qrcode/ui/QrImageCodeChooser.kt index d479f90c9d..ec11c7dceb 100644 --- a/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/qrcode/ui/QrImageCodeChooser.kt +++ b/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/qrcode/ui/QrImageCodeChooser.kt @@ -30,8 +30,9 @@ import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.MaterialTheme import androidx.compose.material3.ModalBottomSheet +import androidx.compose.material3.SheetValue import androidx.compose.material3.Text -import androidx.compose.material3.rememberModalBottomSheetState +import androidx.compose.material3.rememberBottomSheetState import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.text.font.FontWeight @@ -82,7 +83,11 @@ fun QrImageCodeChooser( onPick: (ScannedPayload) -> Unit, onDismiss: () -> Unit, ) { - val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true) + val sheetState = + rememberBottomSheetState( + initialValue = SheetValue.Hidden, + enabledValues = setOf(SheetValue.Hidden, SheetValue.Expanded), + ) ModalBottomSheet(onDismissRequest = onDismiss, sheetState = sheetState) { Column( diff --git a/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/qrcode/ui/ScanOutcomeSheet.kt b/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/qrcode/ui/ScanOutcomeSheet.kt index 5b935f6a0d..d8da3c7c51 100644 --- a/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/qrcode/ui/ScanOutcomeSheet.kt +++ b/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/qrcode/ui/ScanOutcomeSheet.kt @@ -30,9 +30,10 @@ import androidx.compose.material3.Button import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.MaterialTheme import androidx.compose.material3.ModalBottomSheet +import androidx.compose.material3.SheetValue import androidx.compose.material3.Text import androidx.compose.material3.TextButton -import androidx.compose.material3.rememberModalBottomSheetState +import androidx.compose.material3.rememberBottomSheetState import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier import androidx.compose.ui.text.font.FontWeight @@ -73,7 +74,11 @@ fun ScanOutcomeSheet( onOpenLink: (String) -> Unit, onCopy: (String) -> Unit, ) { - val sheetState = rememberModalBottomSheetState(skipPartiallyExpanded = true) + val sheetState = + rememberBottomSheetState( + initialValue = SheetValue.Hidden, + enabledValues = setOf(SheetValue.Hidden, SheetValue.Expanded), + ) ModalBottomSheet(onDismissRequest = onDismiss, sheetState = sheetState) { Column( diff --git a/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/OutlinedThinPaddingTextField.kt b/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/OutlinedThinPaddingTextField.kt index d7e7a537ec..5b93a17366 100644 --- a/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/OutlinedThinPaddingTextField.kt +++ b/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/components/OutlinedThinPaddingTextField.kt @@ -88,7 +88,7 @@ fun OutlinedThinPaddingTextField( shape: Shape = OutlinedTextFieldDefaults.shape, colors: TextFieldColors = OutlinedTextFieldDefaults.colors(), contentPadding: PaddingValues = - OutlinedTextFieldDefaults.contentPadding( + OutlinedTextFieldDefaults.contentPaddingWithoutLabel( start = 10.dp, top = 12.dp, end = 10.dp, diff --git a/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/layouts/listItem/SlimListItemLayout.kt b/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/layouts/listItem/SlimListItemLayout.kt index b7ac7505f8..ec66014409 100644 --- a/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/layouts/listItem/SlimListItemLayout.kt +++ b/commonsUI/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/layouts/listItem/SlimListItemLayout.kt @@ -78,7 +78,7 @@ fun SlimListItem( ) { val decoratedHeadlineContent: @Composable () -> Unit = { ProvideTextStyleFromToken( - colors.headlineColor, + colors.contentColor, MaterialTheme.typography.bodyLarge, headlineContent, ) @@ -88,7 +88,7 @@ fun SlimListItem( { Box(SupportingContentTopPadding) { ProvideTextStyleFromToken( - colors.supportingTextColor, + colors.supportingContentColor, MaterialTheme.typography.bodyMedium, it, ) @@ -99,7 +99,7 @@ fun SlimListItem( overlineContent?.let { { ProvideTextStyleFromToken( - colors.overlineColor, + colors.overlineContentColor, MaterialTheme.typography.labelSmall, it, ) @@ -110,7 +110,7 @@ fun SlimListItem( { Box(LeadingContentEndPadding) { CompositionLocalProvider( - LocalContentColor provides colors.leadingIconColor, + LocalContentColor provides colors.leadingContentColor, content = it, ) } @@ -121,7 +121,7 @@ fun SlimListItem( { Box(TrailingContentStartPadding) { ProvideTextStyleFromToken( - colors.trailingIconColor, + colors.trailingContentColor, MaterialTheme.typography.labelSmall, content = it, ) diff --git a/commonsUI/src/jvmTest/kotlin/com/vitorpamplona/amethyst/commons/sno/SnoObjectCardRenderTest.kt b/commonsUI/src/jvmTest/kotlin/com/vitorpamplona/amethyst/commons/sno/SnoObjectCardRenderTest.kt index 13533a9532..263a05c844 100644 --- a/commonsUI/src/jvmTest/kotlin/com/vitorpamplona/amethyst/commons/sno/SnoObjectCardRenderTest.kt +++ b/commonsUI/src/jvmTest/kotlin/com/vitorpamplona/amethyst/commons/sno/SnoObjectCardRenderTest.kt @@ -80,7 +80,7 @@ class SnoObjectCardRenderTest { MaterialTheme(colorScheme = darkColorScheme()) { Surface(color = MaterialTheme.colorScheme.surface) { Column(Modifier.fillMaxSize()) { - SnoObjectCard(payload = payload!!, eventId = "render-test", onClick = {}) + SnoObjectCard(payload = payload, eventId = "render-test", onClick = {}) } } } @@ -122,7 +122,7 @@ class SnoObjectCardRenderTest { MaterialTheme(colorScheme = darkColorScheme()) { Surface(color = MaterialTheme.colorScheme.surface) { SnoObjectViewer( - payload = payload!!, + payload = payload, eventId = "viewer-test", modifier = Modifier.size(200.dp), ) diff --git a/desktopApp/src/jvmTest/kotlin/com/vitorpamplona/amethyst/desktop/cache/DesktopDmRelayListConsumeTest.kt b/desktopApp/src/jvmTest/kotlin/com/vitorpamplona/amethyst/desktop/cache/DesktopDmRelayListConsumeTest.kt index ee625359b3..d9c520e706 100644 --- a/desktopApp/src/jvmTest/kotlin/com/vitorpamplona/amethyst/desktop/cache/DesktopDmRelayListConsumeTest.kt +++ b/desktopApp/src/jvmTest/kotlin/com/vitorpamplona/amethyst/desktop/cache/DesktopDmRelayListConsumeTest.kt @@ -36,6 +36,14 @@ import kotlin.test.assertNull * kind:10050 routing + `UserContext` wiring, `route` dropped kind 10050 and the * User model was backed by a map nothing populated, so every recipient looked * "unreachable via NIP-17" until an indexer fan-out ran. + * + * Each test takes the [com.vitorpamplona.amethyst.commons.model.User] *before* + * consuming and keeps it. The cache's users and addressable notes live in a + * weakly-valued `LargeSoftCache`, so a note nothing references can be collected + * between two `consume` calls — taking the stored kind 10050 with it and letting + * a stale list land on a fresh, empty note. The app keeps a DM recipient's `User` + * alive while it is in use, and a `User` strongly holds its `dmRelayListNote`; + * the tests do the same, otherwise a GC mid-test made them fail on CI. */ class DesktopDmRelayListConsumeTest { private val relayUrl = NormalizedRelayUrl("wss://relay.test/") @@ -56,11 +64,11 @@ class DesktopDmRelayListConsumeTest { fun `consume routes kind 10050 into the User model`() { val cache = DesktopLocalCache() val signer = NostrSignerSync(KeyPair()) + val user = cache.getOrCreateUser(signer.pubKey) val event = signedDmRelayList(signer) cache.consume(event, relayUrl) - val user = cache.getOrCreateUser(signer.pubKey) assertEquals(dmInbox, user.dmInboxRelaysStrict()) } @@ -76,25 +84,27 @@ class DesktopDmRelayListConsumeTest { fun `a newer kind 10050 replaces an older one`() { val cache = DesktopLocalCache() val signer = NostrSignerSync(KeyPair()) + val user = cache.getOrCreateUser(signer.pubKey) cache.consume(signedDmRelayList(signer, dmInbox, createdAt = 1_700_000_000), relayUrl) val newerRelays = listOf(NormalizedRelayUrl("wss://moved.example/")) cache.consume(signedDmRelayList(signer, newerRelays, createdAt = 1_700_000_100), relayUrl) - assertEquals(newerRelays, cache.getOrCreateUser(signer.pubKey).dmInboxRelaysStrict()) + assertEquals(newerRelays, user.dmInboxRelaysStrict()) } @Test fun `an older kind 10050 does not overwrite a newer one`() { val cache = DesktopLocalCache() val signer = NostrSignerSync(KeyPair()) + val user = cache.getOrCreateUser(signer.pubKey) cache.consume(signedDmRelayList(signer, dmInbox, createdAt = 1_700_000_100), relayUrl) val staleRelays = listOf(NormalizedRelayUrl("wss://stale.example/")) cache.consume(signedDmRelayList(signer, staleRelays, createdAt = 1_700_000_000), relayUrl) - assertEquals(dmInbox, cache.getOrCreateUser(signer.pubKey).dmInboxRelaysStrict()) + assertEquals(dmInbox, user.dmInboxRelaysStrict()) } }