From b0bb2885ead8a24d89e699e4da96ed851cf5ab7c Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 27 May 2026 02:39:56 +0000 Subject: [PATCH] ui(cashu): @Preview composables for the new wallet bits MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Adds Android-Studio-visible previews for the recently-authored composables on the Cashu wallet stack, so designers / reviewers can eyeball them without building and launching the app. All previews use the existing ThemeComparisonColumn helper to render dark + light side by side, matching the convention used by SensitivityWarning and the other existing preview files. CashuWalletSettingsScreen: - SettingsRow (with + without subtitle) - EmptyRecommendationsHint - AddRecommendationRow (empty + typing state) - RecommendationSuggestionList - RecommendationRow (plain + with review text) AddCashuWalletScreen: - MintSuggestionList (multi + single) For RecommendationRow a tiny `fakeRecommendation` helper builds a synthetic kind:38000 with stable tag layout (d / k / u) so the preview exercises the same `mintUrls()` + `dTag()` paths the real renderer uses without touching the signer. Skipped: top-level screen composables (CashuWalletSettingsScreen, CashuWalletScreen, AddCashuWalletScreen) — those take AccountViewModel / CashuWalletViewModel / INav, which can't be cheaply faked. Anyone who needs to see them previewed should iterate on the smaller sub- composables included here. https://claude.ai/code/session_01MdWddiar819f8XYt5N8BjP --- .../loggedIn/wallet/AddCashuWalletScreen.kt | 33 +++++ .../wallet/CashuWalletSettingsScreen.kt | 131 ++++++++++++++++++ 2 files changed, 164 insertions(+) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/AddCashuWalletScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/AddCashuWalletScreen.kt index f4d25c4e90..0036cff4c7 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/AddCashuWalletScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/AddCashuWalletScreen.kt @@ -60,6 +60,7 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel import com.vitorpamplona.amethyst.R @@ -69,6 +70,7 @@ import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.stringRes +import com.vitorpamplona.amethyst.ui.theme.ThemeComparisonColumn @OptIn(ExperimentalMaterial3Api::class) @Composable @@ -463,3 +465,34 @@ private fun MintSuggestionList( } } } + +// ============================================================ +// @Preview composables — Android Studio rendering only +// ============================================================ + +@Preview +@Composable +fun MintSuggestionListPreview() { + ThemeComparisonColumn { + MintSuggestionList( + suggestions = + listOf( + "https://mint.minibits.cash/bitcoin", + "https://mint.coinos.io", + "https://nutmix.cash", + ), + onPick = {}, + ) + } +} + +@Preview +@Composable +fun MintSuggestionListSinglePreview() { + ThemeComparisonColumn { + MintSuggestionList( + suggestions = listOf("https://mint.minibits.cash/bitcoin"), + onPick = {}, + ) + } +} diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/CashuWalletSettingsScreen.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/CashuWalletSettingsScreen.kt index 69da5d8f5b..021becafe6 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/CashuWalletSettingsScreen.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/wallet/CashuWalletSettingsScreen.kt @@ -57,6 +57,7 @@ import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.text.font.FontWeight +import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel import com.vitorpamplona.amethyst.R @@ -68,6 +69,7 @@ import com.vitorpamplona.amethyst.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.navigation.routes.Route import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.stringRes +import com.vitorpamplona.amethyst.ui.theme.ThemeComparisonColumn import com.vitorpamplona.quartz.nip87Ecash.recommendation.MintRecommendationEvent /** @@ -453,3 +455,132 @@ private fun RecommendationRow( } } } + +// ============================================================ +// @Preview composables — Android Studio rendering only +// ============================================================ +// Each preview is rendered in both dark and light themes via +// ThemeComparisonColumn so we can eyeball both at once. Plain-data +// composables only — anything that takes AccountViewModel / INav / +// CashuWalletViewModel can't be cheaply mocked, so those are skipped. + +/** Synthesise a [MintRecommendationEvent] for previews without touching the signer. */ +private fun fakeRecommendation( + mintUrl: String, + review: String = "", +): MintRecommendationEvent = + MintRecommendationEvent( + id = "0".repeat(64), + pubKey = "1".repeat(64), + createdAt = 1_700_000_000L, + tags = + arrayOf( + arrayOf("d", mintUrl), + arrayOf("k", "38172"), + arrayOf("u", mintUrl), + ), + content = review, + sig = "2".repeat(128), + ) + +@Preview +@Composable +fun SettingsRowEditWalletPreview() { + ThemeComparisonColumn { + SettingsRow( + icon = MaterialSymbols.Edit, + title = "Edit wallet details", + subtitle = "Mints, nutzap key", + onClick = {}, + ) + } +} + +@Preview +@Composable +fun SettingsRowNoSubtitlePreview() { + ThemeComparisonColumn { + SettingsRow( + icon = MaterialSymbols.Settings, + title = "Some setting", + subtitle = null, + onClick = {}, + ) + } +} + +@Preview +@Composable +fun EmptyRecommendationsHintPreview() { + ThemeComparisonColumn { + EmptyRecommendationsHint() + } +} + +@Preview +@Composable +fun AddRecommendationRowEmptyPreview() { + ThemeComparisonColumn { + AddRecommendationRow( + input = "", + onInputChange = {}, + canAdd = false, + onAdd = {}, + ) + } +} + +@Preview +@Composable +fun AddRecommendationRowTypingPreview() { + ThemeComparisonColumn { + AddRecommendationRow( + input = "https://mint.minibits.cash", + onInputChange = {}, + canAdd = true, + onAdd = {}, + ) + } +} + +@Preview +@Composable +fun RecommendationSuggestionListPreview() { + ThemeComparisonColumn { + RecommendationSuggestionList( + suggestions = + listOf( + "https://mint.minibits.cash/bitcoin", + "https://mint.coinos.io", + "https://nutmix.cash", + ), + onPick = {}, + ) + } +} + +@Preview +@Composable +fun RecommendationRowPreview() { + ThemeComparisonColumn { + RecommendationRow( + event = fakeRecommendation("https://mint.minibits.cash/bitcoin"), + onDelete = {}, + ) + } +} + +@Preview +@Composable +fun RecommendationRowWithReviewPreview() { + ThemeComparisonColumn { + RecommendationRow( + event = + fakeRecommendation( + mintUrl = "https://mint.coinos.io", + review = "Fast and reliable, been using for months.", + ), + onDelete = {}, + ) + } +}