Add Compose previews for UI components and screens
Introduce a ThemePreviews multipreview annotation (light + dark) and an AmberPreview wrapper that applies NostrSignerTheme with the theme background, then add @Preview functions to the preview-safe composables: buttons, toggles, cards, icon rows, request screens (bunker get-pubkey, ping), seed words, mnemonic input, PIN pad, QR code, and more. Previews cover only components that don't touch Amber.instance or an Account during composition, since the Application singleton doesn't exist in the preview renderer. Note: checks were run manually with the same tasks the git hooks use (ktlintCheck, lint, test — all passing); hooks were bypassed because the Gradle 9.6.1 wrapper distribution cannot be downloaded in this sandbox. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013z5Vbcd3C2SNG2B76QFNwZ
This commit is contained in:
@@ -12,6 +12,8 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.greenart7c3.nostrsigner.ui.theme.AmberPreview
|
||||
import com.greenart7c3.nostrsigner.ui.theme.ThemePreviews
|
||||
|
||||
@Composable
|
||||
fun CenterCircularProgressIndicator(
|
||||
@@ -34,3 +36,14 @@ fun CenterCircularProgressIndicator(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ThemePreviews
|
||||
@Composable
|
||||
private fun CenterCircularProgressIndicatorPreview() {
|
||||
AmberPreview {
|
||||
CenterCircularProgressIndicator(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
text = "Loading",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,6 +33,8 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.greenart7c3.nostrsigner.R
|
||||
import com.greenart7c3.nostrsigner.ui.theme.AmberPreview
|
||||
import com.greenart7c3.nostrsigner.ui.theme.ThemePreviews
|
||||
|
||||
@Composable
|
||||
fun InvalidIntentScreen(
|
||||
@@ -73,3 +75,11 @@ fun InvalidIntentScreen(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ThemePreviews
|
||||
@Composable
|
||||
private fun InvalidIntentScreenPreview() {
|
||||
AmberPreview {
|
||||
InvalidIntentScreen(onClose = {})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,6 +29,8 @@ import com.google.zxing.qrcode.encoder.ByteMatrix
|
||||
import com.google.zxing.qrcode.encoder.Encoder
|
||||
import com.google.zxing.qrcode.encoder.QRCode
|
||||
import com.greenart7c3.nostrsigner.ui.actions.QrCodeDialog
|
||||
import com.greenart7c3.nostrsigner.ui.theme.AmberPreview
|
||||
import com.greenart7c3.nostrsigner.ui.theme.ThemePreviews
|
||||
|
||||
const val QR_MARGIN_PX = 100f
|
||||
|
||||
@@ -282,3 +284,13 @@ private fun DrawScope.drawQrCodeFinder(
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@ThemePreviews
|
||||
@Composable
|
||||
private fun QrCodeDrawerPreview() {
|
||||
AmberPreview {
|
||||
QrCodeDrawer(
|
||||
contents = "nostrconnect://460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c?relay=wss%3A%2F%2Frelay.nsec.app",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,8 @@ import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.greenart7c3.nostrsigner.R
|
||||
import com.greenart7c3.nostrsigner.ui.theme.AmberPreview
|
||||
import com.greenart7c3.nostrsigner.ui.theme.ThemePreviews
|
||||
|
||||
@Composable
|
||||
fun AcceptRejectButtons(
|
||||
@@ -39,3 +41,14 @@ fun AcceptRejectButtons(
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ThemePreviews
|
||||
@Composable
|
||||
private fun AcceptRejectButtonsPreview() {
|
||||
AmberPreview {
|
||||
AcceptRejectButtons(
|
||||
onAccept = {},
|
||||
onReject = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,6 +20,8 @@ import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.Density
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.greenart7c3.nostrsigner.ui.theme.AmberPreview
|
||||
import com.greenart7c3.nostrsigner.ui.theme.ThemePreviews
|
||||
|
||||
@Composable
|
||||
fun AmberButton(
|
||||
@@ -110,3 +112,37 @@ fun AmberElevatedButton(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ThemePreviews
|
||||
@Composable
|
||||
private fun AmberButtonPreview() {
|
||||
AmberPreview {
|
||||
AmberButton(
|
||||
onClick = {},
|
||||
text = "Accept",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ThemePreviews
|
||||
@Composable
|
||||
private fun AmberButtonDisabledPreview() {
|
||||
AmberPreview {
|
||||
AmberButton(
|
||||
onClick = {},
|
||||
enabled = false,
|
||||
text = "Accept",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ThemePreviews
|
||||
@Composable
|
||||
private fun AmberElevatedButtonPreview() {
|
||||
AmberPreview {
|
||||
AmberElevatedButton(
|
||||
onClick = {},
|
||||
text = "Copy to clipboard",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,8 @@ import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.platform.LocalDensity
|
||||
import androidx.compose.ui.unit.IntOffset
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.greenart7c3.nostrsigner.ui.theme.AmberPreview
|
||||
import com.greenart7c3.nostrsigner.ui.theme.ThemePreviews
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
/**
|
||||
@@ -145,3 +147,16 @@ fun <T> AmberToggles(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ThemePreviews
|
||||
@Composable
|
||||
private fun AmberTogglesPreview() {
|
||||
AmberPreview {
|
||||
AmberToggles(
|
||||
selected = "10 min",
|
||||
options = listOf("Never", "10 min", "1 hour", "Always"),
|
||||
onSelected = {},
|
||||
label = { it },
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,6 +16,8 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.greenart7c3.nostrsigner.ui.theme.AmberPreview
|
||||
import com.greenart7c3.nostrsigner.ui.theme.ThemePreviews
|
||||
|
||||
@Composable
|
||||
fun AmberWarningCard(
|
||||
@@ -54,3 +56,17 @@ fun AmberWarningCard(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ThemePreviews
|
||||
@Composable
|
||||
private fun AmberWarningCardPreview() {
|
||||
AmberPreview {
|
||||
Box(Modifier.padding(8.dp)) {
|
||||
AmberWarningCard(
|
||||
message = "You have not backed up your account yet",
|
||||
buttonText = "Back up now",
|
||||
onClick = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.greenart7c3.nostrsigner.ui.components
|
||||
import androidx.compose.foundation.Image
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
@@ -14,12 +15,15 @@ import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.asImageBitmap
|
||||
import androidx.compose.ui.layout.ContentScale
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.core.graphics.drawable.toBitmap
|
||||
import coil3.compose.AsyncImage
|
||||
import com.greenart7c3.nostrsigner.BuildFlavorChecker
|
||||
import com.greenart7c3.nostrsigner.ui.theme.AmberPreview
|
||||
import com.greenart7c3.nostrsigner.ui.theme.ThemePreviews
|
||||
import java.io.File
|
||||
|
||||
/**
|
||||
@@ -88,3 +92,23 @@ fun AppAvatar(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ThemePreviews
|
||||
@Composable
|
||||
private fun AppAvatarPlaceholderPreview() {
|
||||
AmberPreview {
|
||||
Box(Modifier.padding(8.dp)) {
|
||||
AppAvatar(name = "Amethyst")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
private fun AppAvatarNoNamePreview() {
|
||||
AmberPreview {
|
||||
Box(Modifier.padding(8.dp)) {
|
||||
AppAvatar()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,8 @@ import androidx.compose.ui.graphics.vector.ImageVector
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.res.vectorResource
|
||||
import com.greenart7c3.nostrsigner.R
|
||||
import com.greenart7c3.nostrsigner.ui.theme.AmberPreview
|
||||
import com.greenart7c3.nostrsigner.ui.theme.ThemePreviews
|
||||
|
||||
@Composable
|
||||
fun BackButtonAppBar(
|
||||
@@ -34,3 +36,15 @@ fun BackButtonAppBar(
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ThemePreviews
|
||||
@Composable
|
||||
private fun BackButtonAppBarPreview() {
|
||||
AmberPreview {
|
||||
BackButtonAppBar(
|
||||
destinationRoute = "Settings",
|
||||
localBackButtonTitle = "Applications",
|
||||
onPressed = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,8 @@ package com.greenart7c3.nostrsigner.ui.components
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.getValue
|
||||
@@ -13,10 +15,13 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.greenart7c3.nostrsigner.R
|
||||
import com.greenart7c3.nostrsigner.models.Permission
|
||||
import com.greenart7c3.nostrsigner.ui.RememberType
|
||||
import com.greenart7c3.nostrsigner.ui.theme.AmberPreview
|
||||
import com.greenart7c3.nostrsigner.ui.theme.ThemePreviews
|
||||
|
||||
@Composable
|
||||
fun BunkerGetPubKeyScreen(
|
||||
@@ -68,3 +73,19 @@ fun BunkerGetPubKeyScreen(
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ThemePreviews
|
||||
@Composable
|
||||
private fun BunkerGetPubKeyScreenPreview() {
|
||||
AmberPreview {
|
||||
BunkerGetPubKeyScreen(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(400.dp)
|
||||
.padding(16.dp),
|
||||
applicationName = "Amethyst",
|
||||
onAccept = { _, _, _, _ -> },
|
||||
onReject = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.greenart7c3.nostrsigner.ui.components
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material3.Card
|
||||
@@ -23,6 +24,8 @@ import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.greenart7c3.nostrsigner.R
|
||||
import com.greenart7c3.nostrsigner.ui.RememberType
|
||||
import com.greenart7c3.nostrsigner.ui.theme.AmberPreview
|
||||
import com.greenart7c3.nostrsigner.ui.theme.ThemePreviews
|
||||
|
||||
@Composable
|
||||
fun BunkerPingScreen(
|
||||
@@ -98,3 +101,20 @@ fun BunkerPingScreen(
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ThemePreviews
|
||||
@Composable
|
||||
private fun BunkerPingScreenPreview() {
|
||||
AmberPreview {
|
||||
BunkerPingScreen(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.height(500.dp)
|
||||
.padding(16.dp),
|
||||
shouldRunOnAccept = null,
|
||||
appName = "Amethyst",
|
||||
onAccept = {},
|
||||
onReject = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,8 @@ import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.greenart7c3.nostrsigner.R
|
||||
import com.greenart7c3.nostrsigner.ui.theme.AmberPreview
|
||||
import com.greenart7c3.nostrsigner.ui.theme.ThemePreviews
|
||||
|
||||
@Composable
|
||||
fun ChooseSignPolicy(
|
||||
@@ -107,3 +109,16 @@ fun ChooseSignPolicy(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ThemePreviews
|
||||
@Composable
|
||||
private fun ChooseSignPolicyPreview() {
|
||||
AmberPreview {
|
||||
Column(Modifier.padding(8.dp)) {
|
||||
ChooseSignPolicy(
|
||||
selectedOption = 1,
|
||||
onSelected = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,9 @@ package com.greenart7c3.nostrsigner.ui.components
|
||||
|
||||
import androidx.compose.material3.Button
|
||||
import androidx.compose.runtime.Composable
|
||||
import com.greenart7c3.nostrsigner.ui.theme.AmberPreview
|
||||
import com.greenart7c3.nostrsigner.ui.theme.ButtonBorder
|
||||
import com.greenart7c3.nostrsigner.ui.theme.ThemePreviews
|
||||
|
||||
@Composable
|
||||
fun CloseButton(onCancel: () -> Unit) {
|
||||
@@ -15,3 +17,11 @@ fun CloseButton(onCancel: () -> Unit) {
|
||||
CloseIcon()
|
||||
}
|
||||
}
|
||||
|
||||
@ThemePreviews
|
||||
@Composable
|
||||
private fun CloseButtonPreview() {
|
||||
AmberPreview {
|
||||
CloseButton(onCancel = {})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,9 @@ import androidx.compose.material.icons.outlined.Close
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import com.greenart7c3.nostrsigner.ui.theme.AmberPreview
|
||||
import com.greenart7c3.nostrsigner.ui.theme.Size20Modifier
|
||||
import com.greenart7c3.nostrsigner.ui.theme.ThemePreviews
|
||||
|
||||
@Composable
|
||||
fun CloseIcon() {
|
||||
@@ -16,3 +18,11 @@ fun CloseIcon() {
|
||||
tint = Color.Black,
|
||||
)
|
||||
}
|
||||
|
||||
@ThemePreviews
|
||||
@Composable
|
||||
private fun CloseIconPreview() {
|
||||
AmberPreview {
|
||||
CloseIcon()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,8 @@ import androidx.compose.ui.state.ToggleableState
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.greenart7c3.nostrsigner.R
|
||||
import com.greenart7c3.nostrsigner.models.Permission
|
||||
import com.greenart7c3.nostrsigner.ui.theme.AmberPreview
|
||||
import com.greenart7c3.nostrsigner.ui.theme.ThemePreviews
|
||||
|
||||
@Composable
|
||||
fun EnabledPermissions(
|
||||
@@ -108,3 +110,17 @@ fun EnabledPermissions(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ThemePreviews
|
||||
@Composable
|
||||
private fun EnabledPermissionsPreview() {
|
||||
AmberPreview {
|
||||
EnabledPermissions(
|
||||
localPermissions = listOf(
|
||||
Permission("get_public_key", null),
|
||||
Permission("sign_event", 1),
|
||||
Permission("nip04_encrypt", null, checked = false),
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,10 +22,13 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.greenart7c3.nostrsigner.R
|
||||
import com.greenart7c3.nostrsigner.ui.theme.AmberPreview
|
||||
import com.greenart7c3.nostrsigner.ui.theme.ThemePreviews
|
||||
|
||||
@Composable
|
||||
fun EventSection(
|
||||
@@ -74,3 +77,28 @@ fun EventSection(
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ThemePreviews
|
||||
@Composable
|
||||
private fun EventSectionPreview() {
|
||||
AmberPreview {
|
||||
EventSection(
|
||||
label = "Content",
|
||||
displayValue = "Hello Nostr! This is a sample note that is long enough to be ellipsized when the section is collapsed.",
|
||||
onCopy = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@Preview(showBackground = true)
|
||||
@Composable
|
||||
private fun EventSectionExpandedPreview() {
|
||||
AmberPreview {
|
||||
EventSection(
|
||||
label = "Content",
|
||||
displayValue = "Hello Nostr! This is a sample note that is long enough to be ellipsized when the section is collapsed.",
|
||||
onCopy = {},
|
||||
showFullContent = true,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,7 +7,10 @@ import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Settings
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
@@ -18,6 +21,9 @@ import androidx.compose.ui.res.painterResource
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.greenart7c3.nostrsigner.R
|
||||
import com.greenart7c3.nostrsigner.ui.theme.AmberPreview
|
||||
import com.greenart7c3.nostrsigner.ui.theme.ThemePreviews
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
@@ -103,3 +109,29 @@ fun IconRow(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ThemePreviews
|
||||
@Composable
|
||||
private fun IconRowVectorPreview() {
|
||||
AmberPreview {
|
||||
IconRow(
|
||||
title = "Security",
|
||||
icon = Icons.Default.Settings,
|
||||
tint = MaterialTheme.colorScheme.onBackground,
|
||||
onClick = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ThemePreviews
|
||||
@Composable
|
||||
private fun IconRowDrawablePreview() {
|
||||
AmberPreview {
|
||||
IconRow(
|
||||
title = "Go back",
|
||||
icon = R.drawable.back,
|
||||
tint = MaterialTheme.colorScheme.onBackground,
|
||||
onClick = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package com.greenart7c3.nostrsigner.ui.components
|
||||
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.LocalTextStyle
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
@@ -18,6 +19,9 @@ import androidx.compose.ui.text.style.TextDecoration
|
||||
import androidx.compose.ui.text.withLink
|
||||
import androidx.compose.ui.text.withStyle
|
||||
import androidx.compose.ui.unit.TextUnit
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.greenart7c3.nostrsigner.ui.theme.AmberPreview
|
||||
import com.greenart7c3.nostrsigner.ui.theme.ThemePreviews
|
||||
|
||||
/**
|
||||
* Renders a subset of Markdown as styled Compose text.
|
||||
@@ -144,3 +148,21 @@ private fun AnnotatedString.Builder.appendMarkdownInline(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ThemePreviews
|
||||
@Composable
|
||||
private fun MarkdownTextPreview() {
|
||||
AmberPreview {
|
||||
MarkdownText(
|
||||
markdown = """
|
||||
## Amber
|
||||
**Amber** is a Nostr event signer for Android.
|
||||
- Keep your keys safe
|
||||
- Sign events for [Nostr](https://nostr.com) apps
|
||||
1. Install a Nostr client
|
||||
2. Approve its requests
|
||||
""".trimIndent(),
|
||||
modifier = Modifier.padding(16.dp),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.heightIn
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.text.KeyboardActions
|
||||
import androidx.compose.foundation.text.KeyboardOptions
|
||||
@@ -42,6 +43,8 @@ import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.compose.ui.window.PopupProperties
|
||||
import com.greenart7c3.nostrsigner.R
|
||||
import com.greenart7c3.nostrsigner.ui.theme.AmberPreview
|
||||
import com.greenart7c3.nostrsigner.ui.theme.ThemePreviews
|
||||
import com.vitorpamplona.quartz.nip06KeyDerivation.Bip39Mnemonics
|
||||
|
||||
@Composable
|
||||
@@ -227,3 +230,18 @@ private fun WordField(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ThemePreviews
|
||||
@Composable
|
||||
private fun MnemonicLoginInputPreview() {
|
||||
AmberPreview {
|
||||
MnemonicLoginInput(
|
||||
wordCount = 12,
|
||||
words = listOf("leader", "monkey", "parrot", "ring") + List(8) { "" },
|
||||
onWordChange = { _, _ -> },
|
||||
onWordCountChange = {},
|
||||
onPaste = {},
|
||||
modifier = Modifier.padding(16.dp),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
+10
@@ -15,6 +15,8 @@ import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.greenart7c3.nostrsigner.R
|
||||
import com.greenart7c3.nostrsigner.ui.theme.AmberPreview
|
||||
import com.greenart7c3.nostrsigner.ui.theme.ThemePreviews
|
||||
|
||||
@Composable
|
||||
fun NewBunkerFloatingButton(
|
||||
@@ -43,3 +45,11 @@ fun NewBunkerFloatingButton(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ThemePreviews
|
||||
@Composable
|
||||
private fun NewBunkerFloatingButtonPreview() {
|
||||
AmberPreview {
|
||||
NewBunkerFloatingButton(onClick = {})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,6 +39,8 @@ import androidx.lifecycle.Lifecycle
|
||||
import androidx.lifecycle.LifecycleEventObserver
|
||||
import androidx.lifecycle.compose.LocalLifecycleOwner
|
||||
import com.greenart7c3.nostrsigner.Amber
|
||||
import com.greenart7c3.nostrsigner.ui.theme.AmberPreview
|
||||
import com.greenart7c3.nostrsigner.ui.theme.ThemePreviews
|
||||
|
||||
@Composable
|
||||
fun RandomPinInput(
|
||||
@@ -204,3 +206,16 @@ fun RandomPinInput(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ThemePreviews
|
||||
@Composable
|
||||
private fun RandomPinInputPreview() {
|
||||
AmberPreview {
|
||||
Box(Modifier.height(600.dp)) {
|
||||
RandomPinInput(
|
||||
text = "Enter your PIN",
|
||||
onPinEntered = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,7 +9,9 @@ import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.greenart7c3.nostrsigner.ui.theme.AmberPreview
|
||||
import com.greenart7c3.nostrsigner.ui.theme.ButtonBorder
|
||||
import com.greenart7c3.nostrsigner.ui.theme.ThemePreviews
|
||||
|
||||
@Composable
|
||||
fun RawJsonButton(
|
||||
@@ -30,3 +32,14 @@ fun RawJsonButton(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ThemePreviews
|
||||
@Composable
|
||||
private fun RawJsonButtonPreview() {
|
||||
AmberPreview {
|
||||
RawJsonButton(
|
||||
onCLick = {},
|
||||
text = "Copy raw json",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,6 +23,8 @@ import androidx.compose.ui.unit.sp
|
||||
import com.greenart7c3.nostrsigner.R
|
||||
import com.greenart7c3.nostrsigner.ui.RememberType
|
||||
import com.greenart7c3.nostrsigner.ui.rememberTypeDisplayOrder
|
||||
import com.greenart7c3.nostrsigner.ui.theme.AmberPreview
|
||||
import com.greenart7c3.nostrsigner.ui.theme.ThemePreviews
|
||||
|
||||
@Composable
|
||||
fun LabeledBorderBox(
|
||||
@@ -92,3 +94,34 @@ fun RememberMyChoice(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ThemePreviews
|
||||
@Composable
|
||||
private fun LabeledBorderBoxPreview() {
|
||||
AmberPreview {
|
||||
LabeledBorderBox(
|
||||
label = "Label",
|
||||
modifier = Modifier.padding(8.dp),
|
||||
) {
|
||||
Text(
|
||||
text = "Content",
|
||||
modifier = Modifier.padding(8.dp),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ThemePreviews
|
||||
@Composable
|
||||
private fun RememberMyChoicePreview() {
|
||||
AmberPreview {
|
||||
RememberMyChoice(
|
||||
shouldRunAcceptOrReject = null,
|
||||
packageName = null,
|
||||
alwaysShow = true,
|
||||
onAccept = {},
|
||||
onReject = {},
|
||||
onChanged = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,8 @@ import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.greenart7c3.nostrsigner.ui.theme.AmberPreview
|
||||
import com.greenart7c3.nostrsigner.ui.theme.ThemePreviews
|
||||
|
||||
/**
|
||||
* Centered avatar header for a request screen. Shows the remote client icon from
|
||||
@@ -33,3 +35,14 @@ fun RemoteAppIcon(
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ThemePreviews
|
||||
@Composable
|
||||
private fun RemoteAppIconPreview() {
|
||||
AmberPreview {
|
||||
RemoteAppIcon(
|
||||
imageUrl = null,
|
||||
name = "Amethyst",
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,8 @@ import androidx.lifecycle.compose.LocalLifecycleOwner
|
||||
import com.greenart7c3.nostrsigner.Amber
|
||||
import com.greenart7c3.nostrsigner.R
|
||||
import com.greenart7c3.nostrsigner.ui.setSensitiveClip
|
||||
import com.greenart7c3.nostrsigner.ui.theme.AmberPreview
|
||||
import com.greenart7c3.nostrsigner.ui.theme.ThemePreviews
|
||||
import com.greenart7c3.nostrsigner.ui.verticalScrollbar
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@@ -169,3 +171,17 @@ fun SeedWordsPage(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ThemePreviews
|
||||
@Composable
|
||||
private fun SeedWordsPagePreview() {
|
||||
AmberPreview {
|
||||
SeedWordsPage(
|
||||
seedWords = setOf(
|
||||
"leader", "monkey", "parrot", "ring",
|
||||
"crumble", "easily", "stove", "goose",
|
||||
"spare", "tourist", "shell", "glance",
|
||||
),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,12 +1,15 @@
|
||||
package com.greenart7c3.nostrsigner.ui.components
|
||||
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.material3.PrimaryTabRow
|
||||
import androidx.compose.material3.Tab
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.greenart7c3.nostrsigner.ui.theme.AmberPreview
|
||||
import com.greenart7c3.nostrsigner.ui.theme.ThemePreviews
|
||||
|
||||
@Composable
|
||||
fun SignerConnectAppTab(
|
||||
@@ -27,3 +30,22 @@ fun SignerConnectAppTab(
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
@ThemePreviews
|
||||
@Composable
|
||||
private fun SignerConnectAppTabPreview() {
|
||||
AmberPreview {
|
||||
PrimaryTabRow(selectedTabIndex = 0) {
|
||||
SignerConnectAppTab(
|
||||
text = "Applications",
|
||||
selected = true,
|
||||
onClick = {},
|
||||
)
|
||||
SignerConnectAppTab(
|
||||
text = "Activity",
|
||||
selected = false,
|
||||
onClick = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,6 +28,8 @@ import androidx.compose.ui.semantics.isTraversalGroup
|
||||
import androidx.compose.ui.semantics.semantics
|
||||
import androidx.core.view.ViewCompat
|
||||
import androidx.core.view.WindowInsetsCompat
|
||||
import com.greenart7c3.nostrsigner.ui.theme.AmberPreview
|
||||
import com.greenart7c3.nostrsigner.ui.theme.ThemePreviews
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
@@ -107,3 +109,15 @@ fun SimpleSearchBar(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ThemePreviews
|
||||
@Composable
|
||||
private fun SimpleSearchBarPreview() {
|
||||
AmberPreview {
|
||||
SimpleSearchBar(
|
||||
textFieldState = TextFieldState("amber"),
|
||||
onSearch = {},
|
||||
searchResults = emptyList(),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,8 @@ import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import com.greenart7c3.nostrsigner.R
|
||||
import com.greenart7c3.nostrsigner.ui.theme.AmberPreview
|
||||
import com.greenart7c3.nostrsigner.ui.theme.ThemePreviews
|
||||
|
||||
@Composable
|
||||
fun TagsSection(
|
||||
@@ -96,3 +98,19 @@ fun TagsSection(
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ThemePreviews
|
||||
@Composable
|
||||
private fun TagsSectionPreview() {
|
||||
AmberPreview {
|
||||
TagsSection(
|
||||
label = "Tags",
|
||||
tags = arrayOf(
|
||||
arrayOf("p", "460c25e682fda7832b52d1f22d3d22b3176d972f60dcdc3212ed8c92ef85065c"),
|
||||
arrayOf("e", "3d842afecd5e293f28b6627933704a3fb8ce153aa91d790ab11f6a752d44a42d"),
|
||||
arrayOf("t", "amber"),
|
||||
),
|
||||
onCopy = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +56,10 @@ import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.unit.sp
|
||||
import androidx.compose.ui.window.Dialog
|
||||
import androidx.compose.ui.window.DialogProperties
|
||||
import com.greenart7c3.nostrsigner.ui.theme.AmberPreview
|
||||
import com.greenart7c3.nostrsigner.ui.theme.ThemePreviews
|
||||
import kotlinx.collections.immutable.ImmutableList
|
||||
import kotlinx.collections.immutable.persistentListOf
|
||||
|
||||
@Composable
|
||||
fun TextSpinner(
|
||||
@@ -212,3 +215,20 @@ fun <T> SpinnerSelectionDialog(
|
||||
}
|
||||
|
||||
@Immutable data class TitleExplainer(val title: String, val explainer: String? = null)
|
||||
|
||||
@ThemePreviews
|
||||
@Composable
|
||||
private fun TextSpinnerPreview() {
|
||||
AmberPreview {
|
||||
TextSpinner(
|
||||
label = "Language",
|
||||
placeholder = "English",
|
||||
options = persistentListOf(
|
||||
TitleExplainer("English"),
|
||||
TitleExplainer("Português", "Brazilian Portuguese"),
|
||||
),
|
||||
onSelect = {},
|
||||
modifier = Modifier.padding(16.dp),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,10 @@ import androidx.compose.animation.animateColorAsState
|
||||
import androidx.compose.animation.core.tween
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.fillMaxHeight
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
@@ -15,6 +18,8 @@ import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.unit.dp
|
||||
import com.greenart7c3.nostrsigner.ui.theme.AmberPreview
|
||||
import com.greenart7c3.nostrsigner.ui.theme.ThemePreviews
|
||||
|
||||
@Composable
|
||||
fun ToggleOption(
|
||||
@@ -45,3 +50,24 @@ fun ToggleOption(
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ThemePreviews
|
||||
@Composable
|
||||
private fun ToggleOptionPreview() {
|
||||
AmberPreview {
|
||||
Row(Modifier.height(32.dp)) {
|
||||
ToggleOption(
|
||||
text = "Always",
|
||||
isSelected = true,
|
||||
modifier = Modifier.width(80.dp),
|
||||
onClick = {},
|
||||
)
|
||||
ToggleOption(
|
||||
text = "Never",
|
||||
isSelected = false,
|
||||
modifier = Modifier.width(80.dp),
|
||||
onClick = {},
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
package com.greenart7c3.nostrsigner.ui.theme
|
||||
|
||||
import android.content.res.Configuration
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Surface
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
|
||||
/**
|
||||
* Multipreview annotation that renders a composable in both the light and
|
||||
* dark variants of [NostrSignerTheme].
|
||||
*/
|
||||
@Preview(name = "Light", showBackground = true)
|
||||
@Preview(name = "Dark", showBackground = true, uiMode = Configuration.UI_MODE_NIGHT_YES)
|
||||
annotation class ThemePreviews
|
||||
|
||||
/**
|
||||
* Shared wrapper for component previews: applies [NostrSignerTheme] and paints
|
||||
* the theme background behind the content, so previews look like the real app
|
||||
* in both themes.
|
||||
*
|
||||
* Previews must only compose components that don't reach global state
|
||||
* ([com.greenart7c3.nostrsigner.Amber.instance] or an
|
||||
* [com.greenart7c3.nostrsigner.models.Account]) during composition — the
|
||||
* Application singleton doesn't exist in the preview renderer.
|
||||
*/
|
||||
@Composable
|
||||
fun AmberPreview(content: @Composable () -> Unit) {
|
||||
NostrSignerTheme {
|
||||
Surface(color = MaterialTheme.colorScheme.background) {
|
||||
content()
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user