refactor: take the last 353 spacing literals onto the scale, and reach zero

Phase 2, final step, of docs/material-design-conformance.md. Every `.dp` literal in a
spacing position in the UI tree is now a token. 431 reads of `MaterialTheme.spacing.*`, one
reasoned exemption, and `m3-spacing-positions.py` exits 0.

**Shape decides the token, not just the value.** The migration script grew a per-shape
mapping because the same number means different things in different positions: 8dp of
padding is `compactPadding`, 8dp of gap is `itemGap`, and 8dp under a `Spacer` is neither
of those and stays `space100`. Where the pair determines the meaning the semantic name is
used, and nowhere else:

    padding + 8dp   -> compactPadding      10 sites
    padding + 16dp  -> containerPadding    10
    gap     + 4dp   -> relatedGap           8
    gap     + 8dp   -> itemGap             10

That is 38 of 353. The rest take the raw stop, and deliberately: assigning a semantic name
needs somebody to have read what the container *is*, and a name that asserts a meaning the
code does not have is worse than a stop that asserts none. `screenMargin` in particular is
unassignable mechanically -- it is 16dp of padding, exactly like `containerPadding` -- so
it has no call sites yet and gets them when someone reads the screens.

**Two spacers were standing in for zero.** `WriteNewNoteScreen` renders
`Spacer(Modifier.height(1.dp))` twice, in the `LazyColumn` item that shows a reply preview
when there is one. There is nothing to show and the item still has to render something;
1dp was the placeholder. Now `space0`, with a comment, because a 1dp gap that nobody
intended is the kind of thing that gets copied.

**One value is exempt, and says so at the site.** `SovereignWalletStartupScreen`'s
`Spacer(Modifier.height(128.dp))` is room to scroll the last wallet clear of the bottom of
the window -- reserved space, not a step in the rhythm. The scale tops out at `space900`
(72dp) and rounding to it would put the row back under the edge.

Rather than exempt it in the script by value, the classifier now honours an inline
`// m3-spacing-exempt: <reason>` comment on the lines directly above. Exemptions belong at
the call site: the reason travels with the code, a reviewer sees it in the diff that adds
it, and the tool stops accumulating a list of numbers that mean nothing on their own -- the
mistake the first version of this audit made with `DIMENSION_EXEMPT`.

**Where the tokens landed.** `space125` (10dp) 128 times and `space250` (20dp) 107 -- the
two values that already dominated the tree, now named. `space600` (48dp) 52 times, which is
the empty-state spacer from the previous commit. The long tail is 2, 4, 6, 12, 14, 16, 24,
32, 40 and 64dp.

**Verified that nothing moved.** The landing screen was captured on emulator-5554 before
and after and compared pixel by pixel on a 4px grid: **47 differing samples out of
162,000, 0.03%**, and they are the status bar clock. The sweep is a rename.

**Budget ratcheted 353 -> 0**, dated in the file. Phase 8 wires `--check` into CI, at which
point a new `.dp` in a `padding()` fails the build.

**Tests.** 942 pass, 594 jvm over 72 classes and 348 android over 44, unchanged --
`SpacingScaleTest` already asserts the scale, and there is nothing to assert about a
call site having been renamed that the compiler does not.
`:composeApp:compileDebugKotlinAndroid` builds, the debug apk installs and runs,
`m3-audit.sh --check` exits 0. 75 files, 432 insertions, 348 deletions.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
Kgothatso NgakoandClaude Opus 5 committed 2026-09-08 00:36:59 +02:00
1 parent f7a732d68a
commit 8cd0f3f44d
75 files changed
+432 -348

No files matched your search

@@ -51,6 +51,7 @@ import press.mantra.compose.ui.view.model.ActiveProfileViewModel
import press.mantra.compose.ui.view.state.ActiveProfileUIState
import com.vitorpamplona.quartz.nip01Core.core.HexKey
import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent
import press.mantra.compose.ui.theme.spacing
@OptIn(ExperimentalMaterial3ExpressiveApi::class, ExperimentalMaterial3Api::class)
@Composable
@@ -111,14 +112,14 @@ fun ActiveProfileScreen(
) {
LazyColumn(
modifier = Modifier.fillMaxWidth(),
verticalArrangement = Arrangement.spacedBy(10.dp),
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125),
horizontalAlignment = Alignment.CenterHorizontally
) {
item {
Row(
modifier = Modifier.fillMaxWidth().padding(10.dp),
modifier = Modifier.fillMaxWidth().padding(MaterialTheme.spacing.space125),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(10.dp)
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125)
) {
ProfileAvatar(
profile = activeProfileUIState.localNostrEvent.profile,
@@ -140,7 +141,7 @@ fun ActiveProfileScreen(
}
Spacer(
modifier = Modifier.height(10.dp)
modifier = Modifier.height(MaterialTheme.spacing.space125)
)
Text(
@@ -153,7 +154,7 @@ fun ActiveProfileScreen(
item {
Row(
modifier = Modifier.fillMaxWidth().padding(10.dp)
modifier = Modifier.fillMaxWidth().padding(MaterialTheme.spacing.space125)
) {
Spacer(
modifier = Modifier.weight(1f)
@@ -172,7 +173,7 @@ fun ActiveProfileScreen(
)
Spacer(
modifier = Modifier.width(10.dp)
modifier = Modifier.width(MaterialTheme.spacing.space125)
)
Text(
@@ -200,7 +201,7 @@ fun ActiveProfileScreen(
)
Spacer(
modifier = Modifier.width(10.dp)
modifier = Modifier.width(MaterialTheme.spacing.space125)
)
Text(
"Share Profile"
@@ -231,7 +232,7 @@ fun ActiveProfileScreen(
)
Spacer(
modifier = Modifier.width(10.dp)
modifier = Modifier.width(MaterialTheme.spacing.space125)
)
Text(
@@ -256,7 +257,7 @@ fun ActiveProfileScreen(
)
Spacer(
modifier = Modifier.width(10.dp)
modifier = Modifier.width(MaterialTheme.spacing.space125)
)
Text(
@@ -281,7 +282,7 @@ fun ActiveProfileScreen(
)
Spacer(
modifier = Modifier.width(10.dp)
modifier = Modifier.width(MaterialTheme.spacing.space125)
)
Text("Profile Keys")
@@ -303,7 +304,7 @@ fun ActiveProfileScreen(
)
Spacer(
modifier = Modifier.width(10.dp)
modifier = Modifier.width(MaterialTheme.spacing.space125)
)
Text(
@@ -326,7 +327,7 @@ fun ActiveProfileScreen(
)
Spacer(
modifier = Modifier.width(10.dp)
modifier = Modifier.width(MaterialTheme.spacing.space125)
)
Text(
@@ -213,7 +213,7 @@ fun AddArtifactScreen(
// TODO: Check that we have direct message relays for this user...
Column(
modifier = Modifier.fillMaxWidth(),
verticalArrangement = Arrangement.spacedBy(10.dp),
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text("Add Artifact to the group library")
@@ -318,7 +318,7 @@ fun AddArtifactScreen(
} else {
FlowRow(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(8.dp)
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.itemGap)
) {
addArtifactUIState.dialects.forEach { dialect ->
FilterChip(
@@ -338,10 +338,10 @@ fun AddArtifactScreen(
AddArtifactUIState.Loading -> {
Column(
modifier = Modifier.fillMaxWidth().padding(
20.dp
MaterialTheme.spacing.space250
),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(20.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space250)
) {
Spacer(
@@ -200,8 +200,8 @@ fun AddChapterScreen(
}
) { innerPadding ->
Column(
modifier = Modifier.padding(innerPadding).fillMaxSize().padding(20.dp),
verticalArrangement = Arrangement.spacedBy(10.dp)
modifier = Modifier.padding(innerPadding).fillMaxSize().padding(MaterialTheme.spacing.space250),
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125)
) {
if (!addChapterUIState.canSign) {
Text(
@@ -266,9 +266,9 @@ fun AddChapterScreen(
AddChapterUIState.Loading -> {
Column(
modifier = Modifier.fillMaxWidth().padding(20.dp),
modifier = Modifier.fillMaxWidth().padding(MaterialTheme.spacing.space250),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(20.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space250)
) {
Spacer(modifier = Modifier.weight(1f))
Text(
@@ -181,7 +181,7 @@ fun AddDialectScreen(
) {
Column(
modifier = Modifier.fillMaxWidth(),
verticalArrangement = Arrangement.spacedBy(10.dp),
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text("Add a dialect the group can translate into")
@@ -282,10 +282,10 @@ fun AddDialectScreen(
AddDialectUIState.Loading -> {
Column(
modifier = Modifier.fillMaxWidth().padding(
20.dp
MaterialTheme.spacing.space250
),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(20.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space250)
) {
Spacer(
@@ -66,7 +66,7 @@ fun AddMemberToChatRoomConfirmationScreen(
when (val addMemberToChatRoomConfirmationUIState = addMemberToChatRoomConfirmationViewModel.addMemberToChatRoomConfirmationUIState) {
is AddMemberToChatRoomConfirmationUIState.Error -> {
Column(
modifier = Modifier.fillMaxWidth().padding(20.dp),
modifier = Modifier.fillMaxWidth().padding(MaterialTheme.spacing.space250),
horizontalAlignment = Alignment.CenterHorizontally
) {
Spacer(
@@ -127,9 +127,9 @@ fun AddMemberToChatRoomConfirmationScreen(
modifier = Modifier.padding(innerPadding).fillMaxSize()
) {
Column(
modifier = Modifier.weight(1f).fillMaxWidth().padding(20.dp),
modifier = Modifier.weight(1f).fillMaxWidth().padding(MaterialTheme.spacing.space250),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(10.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125)
) {
Spacer(
modifier = Modifier.weight(1f)
@@ -160,10 +160,10 @@ fun AddMemberToChatRoomConfirmationScreen(
AddMemberToChatRoomConfirmationUIState.Loading -> {
Column(
modifier = Modifier.fillMaxWidth().padding(
20.dp
MaterialTheme.spacing.space250
),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(20.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space250)
) {
Spacer(
@@ -208,8 +208,8 @@ fun AddTranslationArtifactVersionScreen(
}
) { innerPadding ->
Column(
modifier = Modifier.padding(innerPadding).fillMaxSize().padding(20.dp),
verticalArrangement = Arrangement.spacedBy(10.dp)
modifier = Modifier.padding(innerPadding).fillMaxSize().padding(MaterialTheme.spacing.space250),
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125)
) {
if (!addTranslationUIState.canSign) {
Text(
@@ -242,7 +242,7 @@ fun AddTranslationArtifactVersionScreen(
FlowRow(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(8.dp)
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.itemGap)
) {
addTranslationUIState.dialects.forEach { dialect ->
FilterChip(
@@ -277,9 +277,9 @@ fun AddTranslationArtifactVersionScreen(
AddTranslationArtifactVersionUIState.Loading -> {
Column(
modifier = Modifier.fillMaxWidth().padding(20.dp),
modifier = Modifier.fillMaxWidth().padding(MaterialTheme.spacing.space250),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(20.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space250)
) {
Spacer(modifier = Modifier.weight(1f))
Text(
@@ -102,8 +102,8 @@ fun ArtifactDetailScreen(
}
) { innerPadding ->
LazyColumn(
modifier = Modifier.padding(innerPadding).fillMaxSize().padding(20.dp),
verticalArrangement = Arrangement.spacedBy(10.dp)
modifier = Modifier.padding(innerPadding).fillMaxSize().padding(MaterialTheme.spacing.space250),
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125)
) {
// Chapters
item {
@@ -166,7 +166,7 @@ fun ArtifactDetailScreen(
Icons.Default.PostAdd,
contentDescription = "Add chapter"
)
Spacer(modifier = Modifier.width(10.dp))
Spacer(modifier = Modifier.width(MaterialTheme.spacing.space125))
Text("Add Chapter")
}
}
@@ -231,7 +231,7 @@ fun ArtifactDetailScreen(
Icons.Default.Translate,
contentDescription = "Add translation"
)
Spacer(modifier = Modifier.width(10.dp))
Spacer(modifier = Modifier.width(MaterialTheme.spacing.space125))
Text("Add Translation")
}
}
@@ -285,9 +285,9 @@ fun ArtifactDetailScreen(
ArtifactDetailUIState.Loading -> {
Column(
modifier = Modifier.fillMaxWidth().padding(20.dp),
modifier = Modifier.fillMaxWidth().padding(MaterialTheme.spacing.space250),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(20.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space250)
) {
Spacer(modifier = Modifier.weight(1f))
Text(
@@ -91,8 +91,8 @@ fun ChapterDetailScreen(
}
) { innerPadding ->
LazyColumn(
modifier = Modifier.padding(innerPadding).fillMaxSize().padding(20.dp),
verticalArrangement = Arrangement.spacedBy(10.dp)
modifier = Modifier.padding(innerPadding).fillMaxSize().padding(MaterialTheme.spacing.space250),
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125)
) {
item {
Text(
@@ -111,7 +111,7 @@ fun ChapterDetailScreen(
item {
Card {
Text(
modifier = Modifier.padding(16.dp),
modifier = Modifier.padding(MaterialTheme.spacing.containerPadding),
text = chapter.originalText,
style = MaterialTheme.typography.bodyMedium
)
@@ -157,9 +157,9 @@ fun ChapterDetailScreen(
ChapterDetailUIState.Loading -> {
Column(
modifier = Modifier.fillMaxWidth().padding(20.dp),
modifier = Modifier.fillMaxWidth().padding(MaterialTheme.spacing.space250),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(20.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space250)
) {
Spacer(modifier = Modifier.weight(1f))
Text(
@@ -28,6 +28,7 @@ import androidx.lifecycle.viewmodel.compose.viewModel
import press.mantra.compose.ui.composable.navigation.routes.Route
import press.mantra.compose.ui.view.model.ChatRoomCreationViewModel
import com.vitorpamplona.quartz.nip01Core.core.HexKey
import press.mantra.compose.ui.theme.spacing
@Composable
fun ChatRoomCreationScreen(
@@ -44,9 +45,9 @@ fun ChatRoomCreationScreen(
) {
Column(
modifier = Modifier.fillMaxWidth().padding(10.dp),
modifier = Modifier.fillMaxWidth().padding(MaterialTheme.spacing.space125),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(10.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125)
) {
TextField(
modifier = Modifier.fillMaxWidth(),
@@ -57,7 +58,7 @@ fun ChatRoomCreationScreen(
Text(
text = it,
modifier = Modifier.padding(
bottom = 8.dp
bottom = MaterialTheme.spacing.compactPadding
)
)
}
@@ -101,7 +102,7 @@ fun ChatRoomCreationScreen(
Text(
text = it,
modifier = Modifier.padding(
bottom = 8.dp
bottom = MaterialTheme.spacing.compactPadding
)
)
}
@@ -123,9 +123,9 @@ fun ChatRoomDetailScreen(
modifier = Modifier.padding(innerPadding).fillMaxSize()
) {
LazyColumn(
modifier = Modifier.weight(1f).fillMaxWidth().padding(20.dp),
modifier = Modifier.weight(1f).fillMaxWidth().padding(MaterialTheme.spacing.space250),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(10.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125)
) {
item {
chatRoomDetailUIState.localChatRoom.chatRoom.description?.let {
@@ -214,7 +214,7 @@ fun ChatRoomDetailScreen(
)
Spacer(
modifier = Modifier.width(10.dp)
modifier = Modifier.width(MaterialTheme.spacing.space125)
)
Text("Add Artifact to Library")
@@ -280,7 +280,7 @@ fun ChatRoomDetailScreen(
)
Spacer(
modifier = Modifier.width(10.dp)
modifier = Modifier.width(MaterialTheme.spacing.space125)
)
Text("Add Dialect")
@@ -323,7 +323,7 @@ fun ChatRoomDetailScreen(
)
Spacer(
modifier = Modifier.width(10.dp)
modifier = Modifier.width(MaterialTheme.spacing.space125)
)
Text("Create project")
@@ -362,7 +362,7 @@ fun ChatRoomDetailScreen(
)
Spacer(
modifier = Modifier.width(10.dp)
modifier = Modifier.width(MaterialTheme.spacing.space125)
)
Text("Shared Key")
@@ -396,7 +396,7 @@ fun ChatRoomDetailScreen(
)
Spacer(
modifier = Modifier.width(10.dp)
modifier = Modifier.width(MaterialTheme.spacing.space125)
)
Text("Proposals")
@@ -423,7 +423,7 @@ fun ChatRoomDetailScreen(
)
Spacer(
modifier = Modifier.width(10.dp)
modifier = Modifier.width(MaterialTheme.spacing.space125)
)
Text("Invite New Member")
@@ -500,7 +500,7 @@ fun ChatRoomDetailScreen(
)
Spacer(
modifier = Modifier.width(10.dp)
modifier = Modifier.width(MaterialTheme.spacing.space125)
)
Text("Leave Group")
@@ -526,7 +526,7 @@ fun ChatRoomDetailScreen(
)
Spacer(
modifier = Modifier.width(10.dp)
modifier = Modifier.width(MaterialTheme.spacing.space125)
)
Text("Delete Group")
@@ -555,10 +555,10 @@ fun ChatRoomDetailScreen(
ChatRoomDetailUIState.Loading -> {
Column(
modifier = Modifier.fillMaxWidth().padding(
20.dp
MaterialTheme.spacing.space250
),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(20.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space250)
) {
Spacer(
@@ -629,7 +629,7 @@ private fun ReindexMarmotGroupEventsButton(
}
Spacer(
modifier = Modifier.width(10.dp)
modifier = Modifier.width(MaterialTheme.spacing.space125)
)
Text("Reindex Events")
@@ -216,8 +216,8 @@ fun ChatRoomMessagingScreen(
modifier = Modifier
.fillMaxWidth()
.background(MaterialTheme.colorScheme.primaryContainer)
.padding(horizontal = 16.dp, vertical = 6.dp),
horizontalArrangement = Arrangement.spacedBy(8.dp),
.padding(horizontal = MaterialTheme.spacing.containerPadding, vertical = MaterialTheme.spacing.space75),
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.itemGap),
verticalAlignment = Alignment.CenterVertically
) {
Icon(
@@ -363,10 +363,10 @@ fun ChatRoomMessagingScreen(
ChatRoomMessagingUIState.Loading -> {
Column(
modifier = Modifier.fillMaxWidth().padding(
20.dp
MaterialTheme.spacing.space250
),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(20.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space250)
) {
Spacer(
@@ -396,10 +396,10 @@ fun ChatRoomMessagingScreen(
ChatRoomMessagingUIState.InitiatingNewChat -> {
Column(
modifier = Modifier.fillMaxWidth().padding(
20.dp
MaterialTheme.spacing.space250
),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(20.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space250)
) {
Spacer(
modifier = Modifier.weight(1f)
@@ -35,6 +35,7 @@ import press.mantra.compose.repository.MarmotRepository
import press.mantra.compose.ui.theme.LocalExtendedColors
import press.mantra.compose.ui.view.model.CreateProfileViewModel
import press.mantra.compose.ui.view.state.CreateProfileUIState
import press.mantra.compose.ui.theme.spacing
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable
@@ -59,10 +60,10 @@ fun CreateProfileScreen(
Column(
modifier = Modifier.fillMaxWidth().padding(
10.dp
MaterialTheme.spacing.space125
),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(20.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space250)
) {
when (val createAccountUIState = createProfileViewModel.createProfileUIState.value) {
@@ -119,7 +120,7 @@ fun CreateProfileScreen(
Text(
text = it,
modifier = Modifier.padding(
bottom = 8.dp
bottom = MaterialTheme.spacing.compactPadding
)
)
}
@@ -163,7 +164,7 @@ fun CreateProfileScreen(
Text(
text = it,
modifier = Modifier.padding(
bottom = 8.dp
bottom = MaterialTheme.spacing.compactPadding
)
)
}
@@ -328,7 +329,7 @@ fun CreateProfileScreen(
}
HorizontalDivider(
modifier = Modifier.padding(20.dp)
modifier = Modifier.padding(MaterialTheme.spacing.space250)
)
Button(
@@ -87,7 +87,7 @@ internal fun DkgApprovalScaffold(
) { padding ->
when (val state = dkgRitualViewModel.dkgRitualUIState) {
is DkgRitualUIState.Loading -> Column(
modifier = Modifier.fillMaxWidth().padding(padding).padding(20.dp),
modifier = Modifier.fillMaxWidth().padding(padding).padding(MaterialTheme.spacing.space250),
horizontalAlignment = Alignment.CenterHorizontally
) {
Spacer(modifier = Modifier.height(MaterialTheme.spacing.space600))
@@ -95,7 +95,7 @@ internal fun DkgApprovalScaffold(
}
is DkgRitualUIState.Error -> Column(
modifier = Modifier.fillMaxWidth().padding(padding).padding(20.dp),
modifier = Modifier.fillMaxWidth().padding(padding).padding(MaterialTheme.spacing.space250),
horizontalAlignment = Alignment.CenterHorizontally
) {
Spacer(modifier = Modifier.height(MaterialTheme.spacing.space600))
@@ -110,7 +110,7 @@ internal fun DkgApprovalScaffold(
// on the way in, which looks exactly like the screen not working.
if (state.session == null) {
Column(
modifier = Modifier.fillMaxWidth().padding(padding).padding(20.dp),
modifier = Modifier.fillMaxWidth().padding(padding).padding(MaterialTheme.spacing.space250),
horizontalAlignment = Alignment.CenterHorizontally
) {
Spacer(modifier = Modifier.height(MaterialTheme.spacing.space600))
@@ -130,11 +130,11 @@ internal fun DkgApprovalScaffold(
modifier = Modifier
.fillMaxWidth()
.padding(padding)
.padding(20.dp),
.padding(MaterialTheme.spacing.space250),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(12.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space150)
) {
Spacer(modifier = Modifier.height(40.dp))
Spacer(modifier = Modifier.height(MaterialTheme.spacing.space500))
Icon(
imageVector = Icons.Default.CheckCircle,
contentDescription = null,
@@ -161,14 +161,14 @@ internal fun DkgApprovalScaffold(
.fillMaxWidth()
.padding(padding)
.verticalScroll(rememberScrollState())
.padding(horizontal = 20.dp, vertical = 16.dp),
verticalArrangement = Arrangement.spacedBy(16.dp)
.padding(horizontal = MaterialTheme.spacing.space250, vertical = MaterialTheme.spacing.containerPadding),
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space200)
) {
body(state)
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(12.dp),
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space150),
verticalAlignment = Alignment.CenterVertically
) {
// Declining is deliberately not a button that refuses on the
@@ -209,7 +209,7 @@ internal fun DkgApprovalScaffold(
internal fun DkgApprovalPoint(text: String) {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(10.dp)
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125)
) {
Text(text = "•", style = MaterialTheme.typography.bodyMedium)
Text(
@@ -14,6 +14,7 @@ import press.mantra.compose.repository.DkgRepository
import com.vitorpamplona.quartz.nip01Core.core.HexKey
import fr.acinq.phoenix.data.ActiveWallet
import kotlinx.coroutines.flow.StateFlow
import press.mantra.compose.ui.theme.spacing
/**
* Asks whether to join a shared key ceremony somebody else opened.
@@ -58,7 +59,7 @@ fun DkgJoinApprovalScreen(
Column(
modifier = Modifier.fillMaxWidth(),
verticalArrangement = Arrangement.spacedBy(8.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.itemGap)
) {
DkgApprovalPoint("Your device publishes the key it will be identified by for the rest of the ceremony.")
DkgApprovalPoint("You will be asked twice more before anything of your key material goes out.")
@@ -111,7 +111,7 @@ fun DkgRitualScreen(
when (val dkgRitualUIState = dkgRitualViewModel.dkgRitualUIState) {
is DkgRitualUIState.Error -> {
Column(
modifier = Modifier.fillMaxWidth().padding(20.dp),
modifier = Modifier.fillMaxWidth().padding(MaterialTheme.spacing.space250),
horizontalAlignment = Alignment.CenterHorizontally
) {
Spacer(modifier = Modifier.height(MaterialTheme.spacing.space600))
@@ -216,8 +216,8 @@ fun DkgRitualScreen(
.padding(innerPadding)
.fillMaxSize()
.verticalScroll(rememberScrollState())
.padding(10.dp),
verticalArrangement = Arrangement.spacedBy(10.dp)
.padding(MaterialTheme.spacing.space125),
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125)
) {
if (session == null) {
Text(
@@ -265,9 +265,9 @@ fun DkgRitualScreen(
}
DkgRitualUIState.Loading -> {
Column(
modifier = Modifier.fillMaxWidth().padding(20.dp),
modifier = Modifier.fillMaxWidth().padding(MaterialTheme.spacing.space250),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(20.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space250)
) {
Spacer(modifier = Modifier.weight(1f))
Text(
@@ -330,11 +330,11 @@ private fun RitualProgress(
) {
Row(
modifier = Modifier.fillMaxWidth().padding(MaterialTheme.spacing.space200),
horizontalArrangement = Arrangement.spacedBy(10.dp),
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125),
verticalAlignment = Alignment.CenterVertically
) {
Icon(Icons.Default.ErrorOutline, contentDescription = null)
Column(verticalArrangement = Arrangement.spacedBy(4.dp)) {
Column(verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.relatedGap)) {
Text("The ceremony was abandoned.", style = MaterialTheme.typography.titleSmall)
session.failureReason?.let {
Text(it, style = MaterialTheme.typography.bodyMedium)
@@ -398,10 +398,10 @@ private fun RitualProgress(
) {
Column(
modifier = Modifier.fillMaxWidth().padding(MaterialTheme.spacing.space200),
verticalArrangement = Arrangement.spacedBy(8.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.itemGap)
) {
Row(
horizontalArrangement = Arrangement.spacedBy(10.dp),
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125),
verticalAlignment = Alignment.CenterVertically
) {
Icon(Icons.Default.CheckCircle, contentDescription = null)
@@ -415,7 +415,7 @@ private fun RitualProgress(
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(10.dp),
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125),
verticalAlignment = Alignment.CenterVertically
) {
// In full, and wrapping rather than ellipsised. This is the
@@ -474,7 +474,7 @@ private fun RitualProgress(
CircularProgressIndicator(modifier = Modifier.size(20.dp))
} else {
Icon(Icons.Default.Groups, contentDescription = null)
Spacer(modifier = Modifier.width(8.dp))
Spacer(modifier = Modifier.width(MaterialTheme.spacing.space100))
Text(text = "Create the #admins group")
}
}
@@ -503,7 +503,7 @@ private fun RitualRoster(
Card(modifier = Modifier.fillMaxWidth()) {
Column(
modifier = Modifier.fillMaxWidth().padding(MaterialTheme.spacing.space200),
verticalArrangement = Arrangement.spacedBy(10.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125)
) {
Text(text = "Members", style = MaterialTheme.typography.titleSmall)
@@ -523,7 +523,7 @@ private fun RitualRoster(
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(10.dp),
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125),
verticalAlignment = Alignment.CenterVertically
) {
Icon(
@@ -565,11 +565,11 @@ private fun RitualStep(
Card(modifier = Modifier.fillMaxWidth()) {
Column(
modifier = Modifier.fillMaxWidth().padding(MaterialTheme.spacing.space200),
verticalArrangement = Arrangement.spacedBy(8.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.itemGap)
) {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(10.dp),
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125),
verticalAlignment = Alignment.CenterVertically
) {
Icon(
@@ -14,6 +14,7 @@ import press.mantra.compose.repository.DkgRepository
import com.vitorpamplona.quartz.nip01Core.core.HexKey
import fr.acinq.phoenix.data.ActiveWallet
import kotlinx.coroutines.flow.StateFlow
import press.mantra.compose.ui.theme.spacing
/**
* Asks whether to contribute to the key itself.
@@ -57,7 +58,7 @@ fun DkgRound1ApprovalScreen(
Column(
modifier = Modifier.fillMaxWidth(),
verticalArrangement = Arrangement.spacedBy(8.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.itemGap)
) {
DkgApprovalPoint(
"Your device publishes its contribution to the key. Every member's is mixed in, " +
@@ -74,7 +75,7 @@ fun DkgRound1ApprovalScreen(
Column(
modifier = Modifier.fillMaxWidth(),
verticalArrangement = Arrangement.spacedBy(4.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.relatedGap)
) {
state.ritualMembers.forEach { member ->
val key = member.participant.participantPublicKey
@@ -14,6 +14,7 @@ import press.mantra.compose.repository.DkgRepository
import com.vitorpamplona.quartz.nip01Core.core.HexKey
import fr.acinq.phoenix.data.ActiveWallet
import kotlinx.coroutines.flow.StateFlow
import press.mantra.compose.ui.theme.spacing
/**
* Asks whether to confirm the combined result.
@@ -59,7 +60,7 @@ fun DkgRound2ApprovalScreen(
Column(
modifier = Modifier.fillMaxWidth(),
verticalArrangement = Arrangement.spacedBy(8.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.itemGap)
) {
DkgApprovalPoint(
"Your device has checked the combined result against what it sent, and they match."
@@ -121,7 +121,7 @@ fun FrostSigningScreen(
is FrostSigningUIState.Loading -> Loading(padding)
is FrostSigningUIState.Error -> Column(
modifier = Modifier.fillMaxWidth().padding(padding).padding(20.dp),
modifier = Modifier.fillMaxWidth().padding(padding).padding(MaterialTheme.spacing.space250),
horizontalAlignment = Alignment.CenterHorizontally
) {
Spacer(modifier = Modifier.height(MaterialTheme.spacing.space600))
@@ -150,7 +150,7 @@ fun FrostSigningScreen(
.padding(padding)
.fillMaxSize()
.verticalScroll(scrollState)
.padding(20.dp),
.padding(MaterialTheme.spacing.space250),
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space200)
) {
WhatIsBeingSigned(proposed, state.items.size)
@@ -267,7 +267,7 @@ fun FrostSigningScreen(
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(10.dp),
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125),
verticalAlignment = Alignment.CenterVertically
) {
Button(
@@ -276,7 +276,7 @@ fun FrostSigningScreen(
onClick = { frostSigningViewModel.approve(onNavigateBack) }
) {
Icon(Icons.Default.Draw, contentDescription = null)
Spacer(modifier = Modifier.width(10.dp))
Spacer(modifier = Modifier.width(MaterialTheme.spacing.space125))
Text("Sign")
}
@@ -305,7 +305,7 @@ fun FrostSigningScreen(
@Composable
private fun Loading(padding: androidx.compose.foundation.layout.PaddingValues) {
Column(
modifier = Modifier.fillMaxWidth().padding(padding).padding(20.dp),
modifier = Modifier.fillMaxWidth().padding(padding).padding(MaterialTheme.spacing.space250),
horizontalAlignment = Alignment.CenterHorizontally
) {
Spacer(modifier = Modifier.height(MaterialTheme.spacing.space600))
@@ -56,6 +56,7 @@ import press.mantra.compose.ui.view.state.HomeScreenUIState
import com.vitorpamplona.quartz.nip01Core.core.HexKey
import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent
import kotlinx.coroutines.launch
import press.mantra.compose.ui.theme.spacing
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
@Composable
@@ -172,7 +173,7 @@ fun HomeScreen(
modifier = Modifier.padding(innerPadding).fillMaxSize()
) {
PrimaryScrollableTabRow(
modifier = Modifier.padding(10.dp),
modifier = Modifier.padding(MaterialTheme.spacing.space125),
edgePadding = 10.dp,
selectedTabIndex = homeScreenViewModel.pagerState.currentPage,
) {
@@ -272,7 +273,7 @@ fun HomeScreen(
private fun HomeScreenPreview() {
TorchTheme {
Surface(
modifier = Modifier.padding(20.dp)
modifier = Modifier.padding(MaterialTheme.spacing.space250)
) {
HomeScreen(
activeUserPublicKey = "",
@@ -4,6 +4,7 @@ import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
@@ -12,6 +13,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import press.mantra.compose.ui.theme.spacing
@Composable
fun ImplementationPendingScreen(
@@ -23,7 +25,7 @@ fun ImplementationPendingScreen(
modifier = Modifier.padding(innerPadding).fillMaxSize()
) {
Column(
modifier = Modifier.padding(20.dp).fillMaxSize(),
modifier = Modifier.padding(MaterialTheme.spacing.space250).fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
@@ -41,7 +43,7 @@ fun ImplementationPendingScreen(
private fun ImplementationPendingScreenPreview() {
press.mantra.compose.ui.theme.TorchTheme {
Surface(
modifier = Modifier.padding(20.dp)
modifier = Modifier.padding(MaterialTheme.spacing.space250)
) {
ImplementationPendingScreen(
"Sign in"
@@ -43,6 +43,7 @@ import press.mantra.compose.ui.composable.widgets.LoadingDataIndicator
import press.mantra.compose.ui.view.model.KeyPackageManagementViewModel
import press.mantra.compose.ui.view.state.KeyPackageManagementUIState
import com.vitorpamplona.quartz.nip01Core.core.HexKey
import press.mantra.compose.ui.theme.spacing
@OptIn(ExperimentalMaterial3ExpressiveApi::class, ExperimentalMaterial3Api::class)
@Composable
@@ -103,7 +104,7 @@ fun KeyPackageManagementScreen(
) {
LazyColumn(
modifier = Modifier.fillMaxWidth(),
verticalArrangement = Arrangement.spacedBy(10.dp),
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125),
horizontalAlignment = Alignment.CenterHorizontally
) {
item {
@@ -118,7 +119,7 @@ fun KeyPackageManagementScreen(
)
Spacer(
modifier = Modifier.width(10.dp)
modifier = Modifier.width(MaterialTheme.spacing.space125)
)
Text(
@@ -19,6 +19,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import press.mantra.compose.ui.theme.spacing
@Composable
fun LandingScreen(
@@ -32,7 +33,7 @@ fun LandingScreen(
) {
Column(
modifier = Modifier.fillMaxWidth(),
verticalArrangement = Arrangement.spacedBy(10.dp),
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
@@ -69,13 +70,13 @@ fun LandingScreen(
Text(
text = "Sign in to Torch via nsec, or remote signer",
modifier = Modifier.padding(10.dp),
modifier = Modifier.padding(MaterialTheme.spacing.space125),
style = MaterialTheme.typography.labelSmall,
textAlign = TextAlign.Center
)
Spacer(
modifier = Modifier.height(20.dp)
modifier = Modifier.height(MaterialTheme.spacing.space250)
)
Button(
@@ -89,7 +90,7 @@ fun LandingScreen(
}
Text(
text = "If you are new to Torch or just want to create a fresh profile",
modifier = Modifier.padding(10.dp),
modifier = Modifier.padding(MaterialTheme.spacing.space125),
style = MaterialTheme.typography.labelSmall,
textAlign = TextAlign.Center
)
@@ -5,6 +5,7 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Scaffold
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
@@ -30,6 +31,7 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey
import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent
import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent
import com.vitorpamplona.quartz.nip18Reposts.RepostEvent
import press.mantra.compose.ui.theme.spacing
@OptIn(ExperimentalMaterial3Api::class)
@Composable
@@ -142,7 +144,7 @@ fun NostrEventDetailScreen(
private fun NostrEventDetailScreenPreview() {
TorchTheme {
Surface(
modifier = Modifier.padding(20.dp)
modifier = Modifier.padding(MaterialTheme.spacing.space250)
) {
NostrEventDetailScreen(
initialNostrEventDetailUIState = NostrEventDetailUIState.Loaded(
@@ -117,7 +117,7 @@ fun ProposalListScreen(
) { padding ->
when (val state = proposalListViewModel.proposalListUIState) {
is ProposalListUIState.Loading -> Column(
modifier = Modifier.fillMaxWidth().padding(padding).padding(20.dp),
modifier = Modifier.fillMaxWidth().padding(padding).padding(MaterialTheme.spacing.space250),
horizontalAlignment = Alignment.CenterHorizontally
) {
Spacer(modifier = Modifier.height(MaterialTheme.spacing.space600))
@@ -125,7 +125,7 @@ fun ProposalListScreen(
}
is ProposalListUIState.Error -> Column(
modifier = Modifier.fillMaxWidth().padding(padding).padding(20.dp),
modifier = Modifier.fillMaxWidth().padding(padding).padding(MaterialTheme.spacing.space250),
horizontalAlignment = Alignment.CenterHorizontally
) {
Spacer(modifier = Modifier.height(MaterialTheme.spacing.space600))
@@ -144,8 +144,8 @@ fun ProposalListScreen(
}
LazyColumn(
modifier = Modifier.padding(padding).fillMaxSize().padding(20.dp),
verticalArrangement = Arrangement.spacedBy(10.dp)
modifier = Modifier.padding(padding).fillMaxSize().padding(MaterialTheme.spacing.space250),
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125)
) {
if (state.proposals.isEmpty()) {
item {
@@ -287,7 +287,7 @@ private fun ProposalCard(
)
},
supportingContent = {
Column(verticalArrangement = Arrangement.spacedBy(2.dp)) {
Column(verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space25)) {
if (proposal.eventCount > 1) {
Text(
text = "with ${proposal.eventCount - 1} more " +
@@ -101,26 +101,26 @@ fun SearchMemberToAddToChatRoomScreen(
Column(
modifier = Modifier.weight(1f).fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(10.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125)
) {
if (searchMemberToAddToChatRoomUIState.contacts.isEmpty()) {
Spacer(
modifier = Modifier.height(20.dp)
modifier = Modifier.height(MaterialTheme.spacing.space250)
)
Text(
modifier = Modifier.padding(20.dp),
modifier = Modifier.padding(MaterialTheme.spacing.space250),
text = "Currently no contacts. Please search and chat with a few people.",
textAlign = TextAlign.Center
)
Spacer(
modifier = Modifier.height(20.dp)
modifier = Modifier.height(MaterialTheme.spacing.space250)
)
} else {
LazyColumn(
modifier = Modifier.fillMaxWidth().padding(MaterialTheme.spacing.space50),
verticalArrangement = Arrangement.spacedBy(10.dp),
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125),
reverseLayout = true
) {
@@ -172,10 +172,10 @@ fun SearchMemberToAddToChatRoomScreen(
SearchMemberToAddToChatRoomUIState.Loading -> {
Column(
modifier = Modifier.fillMaxWidth().padding(
20.dp
MaterialTheme.spacing.space250
),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(20.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space250)
) {
Spacer(
@@ -237,7 +237,7 @@ fun SearchResultScreen(
LazyColumn(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(10.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125)
) {
items(
items = searchResultListUIState.localNostrEvents,
@@ -295,7 +295,7 @@ fun SearchResultScreen(
private fun SearchResultScreenPreview() {
press.mantra.compose.ui.theme.TorchTheme {
Surface(
modifier = Modifier.padding(20.dp)
modifier = Modifier.padding(MaterialTheme.spacing.space250)
) {
SearchResultScreen(
activeUserPublicKey = "",
@@ -61,6 +61,7 @@ import press.mantra.compose.ui.composable.widgets.profile.ProfileColor
import press.mantra.compose.ui.theme.TorchTheme
import press.mantra.compose.ui.view.model.SearchViewModel
import press.mantra.compose.ui.view.state.SearchUIState
import press.mantra.compose.ui.theme.spacing
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
@Composable
@@ -277,11 +278,11 @@ fun SearchScreen(
if (searchableProfiles.isNotEmpty()) {
Column(
modifier = Modifier.fillMaxWidth(),
verticalArrangement = Arrangement.spacedBy(10.dp),
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125),
horizontalAlignment = Alignment.Start
) {
Column(
modifier = Modifier.padding(10.dp),
modifier = Modifier.padding(MaterialTheme.spacing.space125),
) {
Text(
text = "Profiles",
@@ -292,7 +293,7 @@ fun SearchScreen(
LazyRow {
items(searchViewModel.searchableProfiles) { profile ->
Column(
modifier = Modifier.padding(10.dp).width(70.dp),
modifier = Modifier.padding(MaterialTheme.spacing.space125).width(70.dp),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.Center
) {
@@ -336,7 +337,7 @@ fun SearchScreen(
item {
if (searchViewModel.recentSearches.isNotEmpty()) {
Column(
modifier = Modifier.padding(10.dp),
modifier = Modifier.padding(MaterialTheme.spacing.space125),
) {
Text(
text = "Recents",
@@ -389,7 +390,7 @@ fun SearchScreen(
}
Column(
modifier = Modifier.padding(20.dp).fillMaxWidth(),
modifier = Modifier.padding(MaterialTheme.spacing.space250).fillMaxWidth(),
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally
) {
@@ -413,7 +414,7 @@ fun SearchScreen(
private fun SearchScreenPreview() {
TorchTheme {
Surface(
modifier = Modifier.padding(20.dp)
modifier = Modifier.padding(MaterialTheme.spacing.space250)
) {
SearchScreen(
activeUserPublicKey = "",
@@ -74,7 +74,7 @@ fun SelectChatRoomMembersScreen(
when (val selectChatRoomMembersUIState = selectChatRoomMembersViewModel.selectChatRoomMembersUIState) {
is SelectChatRoomMembersUIState.Error -> {
Column(
modifier = Modifier.fillMaxWidth().padding(20.dp),
modifier = Modifier.fillMaxWidth().padding(MaterialTheme.spacing.space250),
horizontalAlignment = Alignment.CenterHorizontally
) {
Spacer(
@@ -144,9 +144,9 @@ fun SelectChatRoomMembersScreen(
) {
if (selectChatRoomMembersUIState.profiles.isEmpty()) {
Column(
modifier = Modifier.weight(1f).fillMaxWidth().padding(20.dp),
modifier = Modifier.weight(1f).fillMaxWidth().padding(MaterialTheme.spacing.space250),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(10.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125)
) {
Spacer(
modifier = Modifier.weight(1f)
@@ -177,7 +177,7 @@ fun SelectChatRoomMembersScreen(
} else {
LazyColumn(
modifier = Modifier.weight(1f).fillMaxWidth().padding(MaterialTheme.spacing.space50),
verticalArrangement = Arrangement.spacedBy(10.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125)
) {
items(
items = selectChatRoomMembersUIState.profiles,
@@ -229,10 +229,10 @@ fun SelectChatRoomMembersScreen(
SelectChatRoomMembersUIState.Loading -> {
Column(
modifier = Modifier.fillMaxWidth().padding(
20.dp
MaterialTheme.spacing.space250
),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(20.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space250)
) {
Spacer(
@@ -92,7 +92,7 @@ fun SelectChatRoomTypeScreen(
when (val selectChatRoomTypeUIState = selectChatRoomTypeViewModel.selectChatRoomTypeUIState) {
is SelectChatRoomTypeUIState.Error -> {
Column(
modifier = Modifier.fillMaxWidth().padding(20.dp),
modifier = Modifier.fillMaxWidth().padding(MaterialTheme.spacing.space250),
horizontalAlignment = Alignment.CenterHorizontally
) {
Spacer(
@@ -174,8 +174,8 @@ fun SelectChatRoomTypeScreen(
.padding(innerPadding)
.fillMaxSize()
.verticalScroll(rememberScrollState())
.padding(10.dp),
verticalArrangement = Arrangement.spacedBy(10.dp)
.padding(MaterialTheme.spacing.space125),
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125)
) {
if (membersNotAdded.isNotEmpty()) {
Card(
@@ -213,7 +213,7 @@ fun SelectChatRoomTypeScreen(
text = "This decides who can change the group later. You can't switch afterwards.",
style = MaterialTheme.typography.labelMedium,
textAlign = TextAlign.Center,
modifier = Modifier.fillMaxWidth().padding(horizontal = 10.dp)
modifier = Modifier.fillMaxWidth().padding(horizontal = MaterialTheme.spacing.space125)
)
ChatRoomTypeCard(
@@ -267,10 +267,10 @@ fun SelectChatRoomTypeScreen(
SelectChatRoomTypeUIState.Loading -> {
Column(
modifier = Modifier.fillMaxWidth().padding(
20.dp
MaterialTheme.spacing.space250
),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(20.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space250)
) {
Spacer(
@@ -330,11 +330,11 @@ private fun ChatRoomTypeCard(
) {
Column(
modifier = Modifier.fillMaxWidth().padding(MaterialTheme.spacing.space200),
verticalArrangement = Arrangement.spacedBy(8.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.itemGap)
) {
Row(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(10.dp),
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125),
verticalAlignment = Alignment.CenterVertically
) {
RadioButton(
@@ -44,6 +44,7 @@ import press.mantra.compose.ui.view.model.ShareProfileViewModel
import press.mantra.compose.ui.view.state.ShareProfileUIState
import com.vitorpamplona.quartz.nip01Core.core.HexKey
import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent
import press.mantra.compose.ui.theme.spacing
@OptIn(ExperimentalMaterial3ExpressiveApi::class, ExperimentalMaterial3Api::class)
@Composable
@@ -104,14 +105,14 @@ fun ShareProfileScreen(
) {
LazyColumn(
modifier = Modifier.fillMaxWidth().weight(1f),
verticalArrangement = Arrangement.spacedBy(10.dp),
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125),
horizontalAlignment = Alignment.CenterHorizontally
) {
item {
Row(
modifier = Modifier.fillMaxWidth().padding(10.dp),
modifier = Modifier.fillMaxWidth().padding(MaterialTheme.spacing.space125),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(10.dp)
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125)
) {
ProfileAvatar(
profile = shareProfileUIState.localNostrEvent.profile,
@@ -137,7 +138,7 @@ fun ShareProfileScreen(
item {
Row(
modifier = Modifier.padding(40.dp)
modifier = Modifier.padding(MaterialTheme.spacing.space500)
) {
QRCodeView(
activeUserPublicKey.hexToNpubHrp()
@@ -147,7 +148,7 @@ fun ShareProfileScreen(
item {
Row(
modifier = Modifier.fillMaxWidth().padding(20.dp)
modifier = Modifier.fillMaxWidth().padding(MaterialTheme.spacing.space250)
) {
val clipboardManager = LocalClipboardManager.current
@@ -167,7 +168,7 @@ fun ShareProfileScreen(
)
Spacer(
modifier = Modifier.width(10.dp)
modifier = Modifier.width(MaterialTheme.spacing.space125)
)
Text(
text = activeUserPublicKey.hexToNpubHrp(),
@@ -180,7 +181,7 @@ fun ShareProfileScreen(
}
Row(
modifier = Modifier.fillMaxWidth().padding(20.dp),
modifier = Modifier.fillMaxWidth().padding(MaterialTheme.spacing.space250),
horizontalArrangement = Arrangement.Center
) {
Button(
@@ -30,6 +30,7 @@ import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import com.vitorpamplona.quartz.nip19Bech32.entities.NPub
import com.vitorpamplona.quartz.nip19Bech32.entities.NSec
import press.mantra.compose.ui.theme.spacing
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable
@@ -50,10 +51,10 @@ fun SignInToProfileScreen(
Column(
modifier = Modifier.fillMaxWidth().padding(
10.dp
MaterialTheme.spacing.space125
),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(20.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space250)
) {
when (val signInToProfileUIState = signInToProfileViewModel.signInToProfileUIState.value) {
@@ -72,7 +73,7 @@ fun SignInToProfileScreen(
Text(
text = it,
modifier = Modifier.padding(
bottom = 8.dp
bottom = MaterialTheme.spacing.compactPadding
)
)
}
@@ -22,6 +22,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import press.mantra.compose.ui.theme.spacing
@Composable
fun SocialPreconditionScreen(
@@ -60,9 +61,9 @@ fun SocialPreconditionScreen(
modifier = Modifier.padding(innerPadding).fillMaxSize()
) {
Column(
modifier = Modifier.fillMaxWidth().padding(20.dp),
modifier = Modifier.fillMaxWidth().padding(MaterialTheme.spacing.space250),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(10.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125)
) {
Text(
@@ -116,7 +117,7 @@ fun SocialPreconditionScreen(
private fun SocialPreconditionScreenPreview() {
press.mantra.compose.ui.theme.TorchTheme {
Surface(
modifier = Modifier.padding(20.dp)
modifier = Modifier.padding(MaterialTheme.spacing.space250)
) {
SocialPreconditionScreen(
onNavigateToSkipForNow = {},
@@ -26,6 +26,7 @@ import fr.acinq.phoenix.utils.preferences.UserPrefs
import fr.acinq.phoenix.utils.preferences.UserWalletMetadata
import fr.acinq.phoenix.utils.preferences.getByWalletIdOrDefault
import kotlinx.coroutines.flow.first
import press.mantra.compose.ui.theme.spacing
@Composable
fun SovereignWalletStartupScreen(
@@ -130,16 +131,22 @@ fun SovereignWalletStartupScreen(
); loadingWallet = it
},
canEdit = false,
modifier = Modifier.padding(horizontal = 24.dp),
modifier = Modifier.padding(horizontal = MaterialTheme.spacing.space300),
topContent = {
Spacer(Modifier.height(64.dp))
Spacer(Modifier.height(MaterialTheme.spacing.space800))
Text(
text = "Select a wallet",
style = MaterialTheme.typography.headlineSmall
)
Spacer(Modifier.height(16.dp))
Spacer(Modifier.height(MaterialTheme.spacing.space200))
},
bottomContent = {
// m3-spacing-exempt: room to scroll the
// last wallet clear of the bottom of the
// window, not a step in the spacing
// rhythm. The scale tops out at 72dp and
// rounding to it would put the last row
// back under the edge.
Spacer(Modifier.height(128.dp))
}
)
@@ -196,17 +203,17 @@ fun SovereignWalletStartupScreen(
}
}
}
Spacer(Modifier.height(16.dp))
Spacer(Modifier.height(MaterialTheme.spacing.space200))
HorizontalDivider(
modifier = Modifier.width(50.dp)
)
Spacer(Modifier.height(24.dp))
Spacer(Modifier.height(MaterialTheme.spacing.space300))
// BorderButton(
// text = stringResource(R.string.startup_error_try_again),
// icon = R.drawable.ic_reset,
// onClick = onTryAgainClick
// )
Spacer(Modifier.height(8.dp))
Spacer(Modifier.height(MaterialTheme.spacing.space100))
// StartErrorShareLogsButton()
}
}
@@ -184,8 +184,8 @@ fun TranslateChunkScreen(
.padding(innerPadding)
.fillMaxSize()
.verticalScroll(rememberScrollState())
.padding(20.dp),
verticalArrangement = Arrangement.spacedBy(10.dp)
.padding(MaterialTheme.spacing.space250),
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125)
) {
if (!translateChunkUIState.canSign) {
Text(
@@ -202,7 +202,7 @@ fun TranslateChunkScreen(
)
Card {
Text(
modifier = Modifier.padding(16.dp),
modifier = Modifier.padding(MaterialTheme.spacing.containerPadding),
text = translateChunkUIState.originalChunk.text,
style = MaterialTheme.typography.bodyMedium
)
@@ -224,9 +224,9 @@ fun TranslateChunkScreen(
TranslateChunkUIState.Loading -> {
Column(
modifier = Modifier.fillMaxWidth().padding(20.dp),
modifier = Modifier.fillMaxWidth().padding(MaterialTheme.spacing.space250),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(20.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space250)
) {
Spacer(modifier = Modifier.weight(1f))
Text(
@@ -104,8 +104,8 @@ fun TranslationArtifactVersionDetailScreen(
}
) { innerPadding ->
LazyColumn(
modifier = Modifier.padding(innerPadding).fillMaxSize().padding(20.dp),
verticalArrangement = Arrangement.spacedBy(10.dp)
modifier = Modifier.padding(innerPadding).fillMaxSize().padding(MaterialTheme.spacing.space250),
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125)
) {
// Chapters the source version has and this translation
// does not. Above the list rather than after it: a chapter
@@ -244,9 +244,9 @@ fun TranslationArtifactVersionDetailScreen(
TranslationArtifactVersionDetailUIState.Loading -> {
Column(
modifier = Modifier.fillMaxWidth().padding(20.dp),
modifier = Modifier.fillMaxWidth().padding(MaterialTheme.spacing.space250),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(20.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space250)
) {
Spacer(modifier = Modifier.weight(1f))
Text(
@@ -123,7 +123,7 @@ fun TranslationChapterScreen(
if (translationChapterUIState.rows.isEmpty()) {
item {
Box(
modifier = Modifier.fillMaxWidth().padding(16.dp),
modifier = Modifier.fillMaxWidth().padding(MaterialTheme.spacing.containerPadding),
contentAlignment = Alignment.Center
) {
Text("This chapter has no chunks.")
@@ -157,9 +157,9 @@ fun TranslationChapterScreen(
TranslationChapterUIState.Loading -> {
Column(
modifier = Modifier.fillMaxWidth().padding(20.dp),
modifier = Modifier.fillMaxWidth().padding(MaterialTheme.spacing.space250),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(20.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space250)
) {
Spacer(modifier = Modifier.weight(1f))
Text(
@@ -223,9 +223,9 @@ private fun TableRow(
Row(
modifier = Modifier.fillMaxWidth().height(IntrinsicSize.Min)
) {
Box(modifier = Modifier.weight(1f).padding(12.dp)) { left() }
Box(modifier = Modifier.weight(1f).padding(MaterialTheme.spacing.space150)) { left() }
VerticalDivider(modifier = Modifier.fillMaxHeight())
Box(modifier = Modifier.weight(1f).then(rightModifier).padding(12.dp)) { right() }
Box(modifier = Modifier.weight(1f).then(rightModifier).padding(MaterialTheme.spacing.space150)) { right() }
}
}
@@ -17,6 +17,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import press.mantra.compose.ui.theme.spacing
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable
@@ -28,10 +29,10 @@ fun UnannouncedProfileScreen() {
Column(
modifier = Modifier.fillMaxWidth().padding(
10.dp
MaterialTheme.spacing.space125
),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(20.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space250)
) {
Spacer(
@@ -17,6 +17,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import press.mantra.compose.ui.theme.spacing
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable
@@ -28,10 +29,10 @@ fun UnindexedProfileScreen() {
Column(
modifier = Modifier.fillMaxWidth().padding(
10.dp
MaterialTheme.spacing.space125
),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(20.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space250)
) {
Spacer(
@@ -17,6 +17,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import press.mantra.compose.ui.theme.spacing
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable
@@ -28,10 +29,10 @@ fun UnqueuedProfileScreen() {
Column(
modifier = Modifier.fillMaxWidth().padding(
10.dp
MaterialTheme.spacing.space125
),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(20.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space250)
) {
Spacer(
@@ -19,6 +19,7 @@ import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.lifecycle.viewmodel.compose.viewModel
import press.mantra.compose.ui.theme.spacing
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable
@@ -42,10 +43,10 @@ fun UnqueuedProfileSynchronizationScreen(
Column(
modifier = Modifier.fillMaxWidth().padding(
10.dp
MaterialTheme.spacing.space125
),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(20.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space250)
) {
Spacer(
@@ -17,6 +17,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import press.mantra.compose.ui.theme.spacing
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable
@@ -28,10 +29,10 @@ fun UnsignedProfileScreen() {
Column(
modifier = Modifier.fillMaxWidth().padding(
10.dp
MaterialTheme.spacing.space125
),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(20.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space250)
) {
Spacer(
@@ -17,6 +17,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import press.mantra.compose.ui.theme.spacing
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable
@@ -30,10 +31,10 @@ fun UnsyncedProfileScreen(
Column(
modifier = Modifier.fillMaxWidth().padding(
10.dp
MaterialTheme.spacing.space125
),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(20.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space250)
) {
Spacer(
@@ -72,10 +72,10 @@ fun WriteNewNoteScreen(
Column(
modifier = Modifier.fillMaxWidth().padding(
10.dp
MaterialTheme.spacing.space125
),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(10.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125)
) {
when (val writeNewNoteUIState = writeNewNoteViewModel.writeNewNoteUIState) {
@@ -98,8 +98,10 @@ fun WriteNewNoteScreen(
onNavigateToEvent = onNavigateToNostrEvent
)
} else {
// Nothing to show, but the LazyColumn item has to
// render something. 1dp was standing in for zero.
Spacer(
modifier = Modifier.height(1.dp)
modifier = Modifier.height(MaterialTheme.spacing.space0)
)
}
}
@@ -112,7 +114,7 @@ fun WriteNewNoteScreen(
Text(
modifier = Modifier.padding(
start = MaterialTheme.spacing.space600,
bottom = 10.dp,
bottom = MaterialTheme.spacing.space125,
),
text = "replying To ${writeNewNoteUIState.inReplyToNostrEvent.profile?.humanReadableNameOrPubkey() ?: "note"}",
@@ -132,7 +134,7 @@ fun WriteNewNoteScreen(
Text(
text = it,
modifier = Modifier.padding(
bottom = 8.dp
bottom = MaterialTheme.spacing.compactPadding
)
)
}
@@ -235,7 +237,7 @@ fun WriteNewNoteScreen(
Card(
modifier = Modifier.padding(
start = MaterialTheme.spacing.space600,
top = 10.dp
top = MaterialTheme.spacing.space125
)
) {
writeNewNoteUIState.quotedNostrEvent.RenderNotePreview(
@@ -294,11 +296,13 @@ fun WriteNewNoteScreen(
HorizontalDivider(
modifier = Modifier.padding(20.dp)
modifier = Modifier.padding(MaterialTheme.spacing.space250)
)
} else {
// Nothing to show, but the LazyColumn item has to
// render something. 1dp was standing in for zero.
Spacer(
modifier = Modifier.height(1.dp)
modifier = Modifier.height(MaterialTheme.spacing.space0)
)
}
}
@@ -306,10 +310,10 @@ fun WriteNewNoteScreen(
item {
Column(
modifier = Modifier.fillParentMaxHeight().fillMaxWidth().padding(
10.dp
MaterialTheme.spacing.space125
),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(10.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125)
) {
Text(
text = writeNewNoteUIState.localProfile.profile.humanReadableNameOrPubkey(),
@@ -43,7 +43,7 @@ fun LoadingDataIndicator(
Text(
text = text,
modifier = Modifier.fillMaxWidth().padding(10.dp),
modifier = Modifier.fillMaxWidth().padding(MaterialTheme.spacing.space125),
textAlign = TextAlign.Center
)
}
@@ -36,6 +36,7 @@ import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.semantics.Role
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.dp
import press.mantra.compose.ui.theme.spacing
@Composable
fun Clickable(
@@ -48,7 +49,7 @@ fun Clickable(
backgroundColor: Color = Color.Unspecified, // transparent by default!
shape: Shape = RectangleShape,
clickDescription: String = "",
internalPadding: PaddingValues = PaddingValues(0.dp),
internalPadding: PaddingValues = PaddingValues(MaterialTheme.spacing.space0),
indication: Indication? = LocalIndication.current,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
content: @Composable () -> Unit,
@@ -20,6 +20,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import press.mantra.compose.ui.theme.spacing
@Composable
private fun ArticleCard(
@@ -50,7 +51,7 @@ private fun ArticleCard(
color = MaterialTheme.colorScheme.surface,
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 6.dp)
.padding(vertical = MaterialTheme.spacing.space75)
.then(
if (onArticleClick != null) Modifier.clickable { onArticleClick(30023, author, dTag) }
else Modifier
@@ -59,14 +60,14 @@ private fun ArticleCard(
if (event == null) {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.padding(14.dp)
modifier = Modifier.padding(MaterialTheme.spacing.space175)
) {
CircularProgressIndicator(
modifier = Modifier.width(14.dp).height(14.dp),
strokeWidth = 2.dp,
color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.5f)
)
Spacer(Modifier.width(8.dp))
Spacer(Modifier.width(MaterialTheme.spacing.space100))
Text(
text = "Loading article...",
style = MaterialTheme.typography.bodyMedium,
@@ -88,18 +89,18 @@ private fun ArticleCard(
// .clip(RoundedCornerShape(topStart = 12.dp, topEnd = 12.dp)),
// )
// }
Column(modifier = Modifier.padding(horizontal = 14.dp, vertical = 10.dp)) {
Column(modifier = Modifier.padding(horizontal = MaterialTheme.spacing.space175, vertical = MaterialTheme.spacing.space125)) {
Row(verticalAlignment = Alignment.CenterVertically) {
Surface(
shape = RoundedCornerShape(4.dp),
color = MaterialTheme.colorScheme.primaryContainer,
modifier = Modifier.padding(end = 8.dp)
modifier = Modifier.padding(end = MaterialTheme.spacing.compactPadding)
) {
Text(
text = "ARTICLE",
style = MaterialTheme.typography.labelSmall,
color = MaterialTheme.colorScheme.onPrimaryContainer,
modifier = Modifier.padding(horizontal = 6.dp, vertical = 2.dp)
modifier = Modifier.padding(horizontal = MaterialTheme.spacing.space75, vertical = MaterialTheme.spacing.space25)
)
}
Text(
@@ -118,19 +119,19 @@ private fun ArticleCard(
color = MaterialTheme.colorScheme.onSurfaceVariant,
maxLines = 3,
overflow = TextOverflow.Ellipsis,
modifier = Modifier.padding(top = 4.dp)
modifier = Modifier.padding(top = MaterialTheme.spacing.space50)
)
}
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.padding(top = 6.dp)
modifier = Modifier.padding(top = MaterialTheme.spacing.space75)
) {
press.mantra.compose.ui.composable.widgets.profile.ProfileAvatar(
profile = profile,
publicKey = localNostrEvent.nostrEvent.pubKey,
size = 20.dp
)
Spacer(Modifier.width(6.dp))
Spacer(Modifier.width(MaterialTheme.spacing.space75))
val displayName = profile?.humanReadableNameOrPubkey()
?: "${author.take(8)}...${author.takeLast(4)}"
Text(
@@ -37,6 +37,8 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties
import coil3.compose.AsyncImage
import androidx.compose.material3.MaterialTheme
import press.mantra.compose.ui.theme.spacing
@Composable
fun FullScreenImageViewer(
@@ -87,7 +89,7 @@ fun FullScreenImageViewer(
Row(
modifier = Modifier
.align(Alignment.TopEnd)
.padding(16.dp)
.padding(MaterialTheme.spacing.containerPadding)
) {
val buttonColors = IconButtonDefaults.iconButtonColors(
containerColor = Color.Black.copy(alpha = 0.5f),
@@ -104,7 +106,7 @@ fun FullScreenImageViewer(
// contentDescription = "Download"
// )
// }
Spacer(Modifier.width(8.dp))
Spacer(Modifier.width(MaterialTheme.spacing.space100))
IconButton(
onClick = { clipboardManager.setText(AnnotatedString(imageUrl)) },
colors = buttonColors,
@@ -112,7 +114,7 @@ fun FullScreenImageViewer(
) {
Icon(Icons.Default.ContentCopy, contentDescription = "Copy URL")
}
Spacer(Modifier.width(8.dp))
Spacer(Modifier.width(MaterialTheme.spacing.space100))
IconButton(
onClick = onDismiss,
colors = buttonColors,
@@ -31,6 +31,7 @@ import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.platform.LocalClipboardManager
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.unit.dp
import press.mantra.compose.ui.theme.spacing
@OptIn(ExperimentalFoundationApi::class)
@Composable
@@ -62,7 +63,7 @@ internal fun ImageWithContextMenu(meta: MediaMeta, onFullScreen: () -> Unit) {
modifier = Modifier.size(40.dp),
tint = MaterialTheme.colorScheme.onSurfaceVariant
)
Spacer(Modifier.height(8.dp))
Spacer(Modifier.height(MaterialTheme.spacing.space100))
Text(
"Tap to load",
style = MaterialTheme.typography.bodySmall,
@@ -33,6 +33,7 @@ import androidx.compose.ui.unit.dp
import fr.acinq.lightning.payment.Bolt11Invoice
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import press.mantra.compose.ui.theme.spacing
@Composable
internal fun LightningInvoiceCard(
@@ -57,7 +58,7 @@ internal fun LightningInvoiceCard(
text = "${decoded.amount?.truncateToSatoshi() ?: "Any amount"}"
)
if (!decoded.description.isNullOrBlank()) {
Spacer(Modifier.height(4.dp))
Spacer(Modifier.height(MaterialTheme.spacing.space50))
Text(
text = decoded.description!!,
style = MaterialTheme.typography.bodySmall,
@@ -97,13 +98,13 @@ internal fun LightningInvoiceCard(
Surface(
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 4.dp),
.padding(vertical = MaterialTheme.spacing.space50),
shape = RoundedCornerShape(12.dp),
color = MaterialTheme.colorScheme.surfaceVariant,
border = BorderStroke(1.dp, primary.copy(alpha = 0.4f))
) {
Row(
modifier = Modifier.padding(horizontal = 12.dp, vertical = 10.dp),
modifier = Modifier.padding(horizontal = MaterialTheme.spacing.space150, vertical = MaterialTheme.spacing.space125),
verticalAlignment = Alignment.CenterVertically
) {
Icon(
@@ -112,7 +113,7 @@ internal fun LightningInvoiceCard(
tint = primary,
modifier = Modifier.size(20.dp)
)
Spacer(Modifier.width(10.dp))
Spacer(Modifier.width(MaterialTheme.spacing.space125))
Column(Modifier.weight(1f)) {
Text(
text = if (decoded.amount != null)
@@ -138,7 +139,7 @@ internal fun LightningInvoiceCard(
}
}
if (onPayInvoice != null) {
Spacer(Modifier.width(8.dp))
Spacer(Modifier.width(MaterialTheme.spacing.space100))
when (payState) {
InvoicePayState.Paying -> CircularProgressIndicator(
modifier = Modifier.size(24.dp),
@@ -24,6 +24,7 @@ import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import coil3.compose.AsyncImage
import io.ktor.http.Url
import press.mantra.compose.ui.theme.spacing
@Composable
internal fun LinkPreview(url: String) {
@@ -47,7 +48,7 @@ internal fun LinkPreview(url: String) {
color = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.3f),
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 4.dp)
.padding(vertical = MaterialTheme.spacing.space50)
.clickable { uriHandler.openUri(url) }
) {
Column {
@@ -62,7 +63,7 @@ internal fun LinkPreview(url: String) {
.clip(RoundedCornerShape(topStart = 12.dp, topEnd = 12.dp))
)
}
Column(modifier = Modifier.padding(12.dp)) {
Column(modifier = Modifier.padding(MaterialTheme.spacing.space150)) {
data.siteName?.let { site ->
Text(
text = site.uppercase(),
@@ -93,7 +94,7 @@ internal fun LinkPreview(url: String) {
color = MaterialTheme.colorScheme.onSurface,
maxLines = 2,
overflow = TextOverflow.Ellipsis,
modifier = Modifier.padding(top = 2.dp)
modifier = Modifier.padding(top = MaterialTheme.spacing.space25)
)
}
data.description?.let { desc ->
@@ -103,7 +104,7 @@ internal fun LinkPreview(url: String) {
color = MaterialTheme.colorScheme.onSurfaceVariant,
maxLines = 3,
overflow = TextOverflow.Ellipsis,
modifier = Modifier.padding(top = 4.dp)
modifier = Modifier.padding(top = MaterialTheme.spacing.space50)
)
}
}
@@ -118,7 +119,7 @@ internal fun LinkPreview(url: String) {
maxLines = 1,
overflow = TextOverflow.Ellipsis,
modifier = Modifier
.padding(vertical = 2.dp)
.padding(vertical = MaterialTheme.spacing.space25)
.clickable { uriHandler.openUri(url) }
)
}
@@ -11,6 +11,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import press.mantra.compose.ui.theme.spacing
@Composable
private fun LiveStreamCard(
@@ -44,7 +45,7 @@ private fun LiveStreamCard(
color = MaterialTheme.colorScheme.surface,
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 6.dp)
.padding(vertical = MaterialTheme.spacing.space75)
.then(
if (onLiveStreamClick != null) Modifier.clickable {
onLiveStreamClick(author, dTag, segmentRelayHints.firstOrNull())
@@ -18,6 +18,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import press.mantra.compose.ui.theme.spacing
@Composable
internal fun LiveStreamCardContent(
@@ -34,14 +35,14 @@ internal fun LiveStreamCardContent(
if (event == null) {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.padding(14.dp)
modifier = Modifier.padding(MaterialTheme.spacing.space175)
) {
CircularProgressIndicator(
modifier = Modifier.width(14.dp).height(14.dp),
strokeWidth = 2.dp,
color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.5f)
)
Spacer(Modifier.width(8.dp))
Spacer(Modifier.width(MaterialTheme.spacing.space100))
Text(
text = "Loading stream...",
style = MaterialTheme.typography.bodyMedium,
@@ -78,32 +79,32 @@ internal fun LiveStreamCardContent(
// .clip(RoundedCornerShape(topStart = 12.dp, topEnd = 12.dp)),
// )
}
Column(modifier = Modifier.padding(horizontal = 14.dp, vertical = 10.dp)) {
Column(modifier = Modifier.padding(horizontal = MaterialTheme.spacing.space175, vertical = MaterialTheme.spacing.space125)) {
Row(verticalAlignment = Alignment.CenterVertically) {
if (status == "live") {
Surface(
shape = RoundedCornerShape(4.dp),
color = Color(0xFFE53935),
modifier = Modifier.padding(end = 8.dp)
modifier = Modifier.padding(end = MaterialTheme.spacing.compactPadding)
) {
Text(
text = "LIVE",
style = MaterialTheme.typography.labelSmall,
color = Color.White,
modifier = Modifier.padding(horizontal = 6.dp, vertical = 2.dp)
modifier = Modifier.padding(horizontal = MaterialTheme.spacing.space75, vertical = MaterialTheme.spacing.space25)
)
}
} else if (status == "ended") {
Surface(
shape = RoundedCornerShape(4.dp),
color = MaterialTheme.colorScheme.surfaceVariant,
modifier = Modifier.padding(end = 8.dp)
modifier = Modifier.padding(end = MaterialTheme.spacing.compactPadding)
) {
Text(
text = "ENDED",
style = MaterialTheme.typography.labelSmall,
color = MaterialTheme.colorScheme.onSurfaceVariant,
modifier = Modifier.padding(horizontal = 6.dp, vertical = 2.dp)
modifier = Modifier.padding(horizontal = MaterialTheme.spacing.space75, vertical = MaterialTheme.spacing.space25)
)
}
}
@@ -123,19 +124,19 @@ internal fun LiveStreamCardContent(
color = MaterialTheme.colorScheme.onSurfaceVariant,
maxLines = 3,
overflow = TextOverflow.Ellipsis,
modifier = Modifier.padding(top = 4.dp)
modifier = Modifier.padding(top = MaterialTheme.spacing.space50)
)
}
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.padding(top = 6.dp)
modifier = Modifier.padding(top = MaterialTheme.spacing.space75)
) {
press.mantra.compose.ui.composable.widgets.profile.ProfileAvatar(
profile = profile,
publicKey = event.pubKey,
size = 20.dp
)
Spacer(Modifier.width(6.dp))
Spacer(Modifier.width(MaterialTheme.spacing.space75))
val displayName = profile?.humanReadableNameOrPubkey()
?: "${author.take(8)}...${author.takeLast(4)}"
Text(
@@ -17,6 +17,7 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.dp
import press.mantra.compose.ui.theme.spacing
@Composable
@@ -48,11 +49,11 @@ internal fun QuotedAddressableNote(
color = MaterialTheme.colorScheme.surface,
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 6.dp)
.padding(vertical = MaterialTheme.spacing.space75)
) {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.padding(14.dp)
modifier = Modifier.padding(MaterialTheme.spacing.space175)
) {
CircularProgressIndicator(
modifier = Modifier
@@ -61,7 +62,7 @@ internal fun QuotedAddressableNote(
strokeWidth = 2.dp,
color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.5f)
)
Spacer(Modifier.width(8.dp))
Spacer(Modifier.width(MaterialTheme.spacing.space100))
Text(
text = "Loading note...",
style = MaterialTheme.typography.bodyMedium,
@@ -19,6 +19,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import com.vitorpamplona.quartz.nip01Core.core.HexKey
import press.mantra.compose.ui.theme.spacing
@Composable
fun QuotedNote(
@@ -56,7 +57,7 @@ fun QuotedNote(
color = MaterialTheme.colorScheme.surface,
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 6.dp)
.padding(vertical = MaterialTheme.spacing.space75)
) {
localQuotedNostrEvent.RenderNotePreview(
onNavigateToEvent = onNavigateToEvent
@@ -87,11 +88,11 @@ fun QuotedNote(
color = MaterialTheme.colorScheme.surface,
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 6.dp)
.padding(vertical = MaterialTheme.spacing.space75)
) {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.padding(14.dp)
modifier = Modifier.padding(MaterialTheme.spacing.space175)
) {
CircularProgressIndicator(
modifier = Modifier
@@ -100,7 +101,7 @@ fun QuotedNote(
strokeWidth = 2.dp,
color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.5f)
)
Spacer(Modifier.width(8.dp))
Spacer(Modifier.width(MaterialTheme.spacing.space100))
Text(
text = "Loading note...",
style = MaterialTheme.typography.bodyMedium,
@@ -116,7 +117,7 @@ fun QuotedNote(
private fun QuotedNotePreview() {
press.mantra.compose.ui.theme.TorchTheme {
Surface(
modifier = Modifier.padding(20.dp)
modifier = Modifier.padding(MaterialTheme.spacing.space250)
) {
QuotedNote(
@@ -31,6 +31,7 @@ import androidx.compose.ui.unit.dp
import co.touchlab.kermit.Logger
import coil3.compose.AsyncImage
import com.vitorpamplona.quartz.nip01Core.core.HexKey
import press.mantra.compose.ui.theme.spacing
@Composable
fun RichContent(
@@ -398,13 +399,13 @@ fun RichContent(
private fun RichContentPreview() {
press.mantra.compose.ui.theme.TorchTheme {
Surface(
modifier = Modifier.padding(20.dp)
modifier = Modifier.padding(MaterialTheme.spacing.space250)
) {
Card(
modifier = Modifier.padding(10.dp)
modifier = Modifier.padding(MaterialTheme.spacing.space125)
) {
RichContent(
modifier = Modifier.padding(10.dp),
modifier = Modifier.padding(MaterialTheme.spacing.space125),
nostrEvent = press.mantra.compose.database.model.NostrEvent(
id = "e5e3ad0272d1fbeead8e439a4ad3453374ca4969c8d2be84025ba4ef8ae5a520",
content = "Something something something nostr:npub1uh366qnj68a7atvwgwdy4569xd6v5jtferftapqztwjwlzh9553q47pqsx\nhttps://www.brainyquote.com/authors/steven-biko-quotes\nnostr:nevent1qqspcusnzxx5u97xht2udvg3yhcq2cvmc0jrxa90lwwdvjplve0atespzpmhxue69uhkummnw3ezuamfdejsyg8h5g639qhuv803hzwexfwhyud6t6suxfu364anddqvrmn9j4cahvxksr8q",
@@ -11,6 +11,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.unit.dp
import press.mantra.compose.ui.theme.spacing
@Composable
internal fun UnsupportedKindBadge(kind: Int?, style: TextStyle) {
@@ -20,13 +21,13 @@ internal fun UnsupportedKindBadge(kind: Int?, style: TextStyle) {
color = MaterialTheme.colorScheme.surfaceVariant.copy(alpha = 0.3f),
modifier = Modifier
.fillMaxWidth()
.padding(vertical = 6.dp)
.padding(vertical = MaterialTheme.spacing.space75)
) {
Text(
text = if (kind != null) "Unsupported event kind: $kind" else "Unsupported event kind",
style = style,
color = MaterialTheme.colorScheme.onSurfaceVariant,
modifier = Modifier.padding(14.dp)
modifier = Modifier.padding(MaterialTheme.spacing.space175)
)
}
}
@@ -57,6 +57,7 @@ import press.mantra.compose.ui.view.model.MetadataEventDetailViewModel
import press.mantra.compose.ui.view.state.MetadataEventDetailUIState
import com.vitorpamplona.quartz.nip01Core.core.HexKey
import com.vitorpamplona.quartz.nip01Core.metadata.MetadataEvent
import press.mantra.compose.ui.theme.spacing
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
@Composable
@@ -110,7 +111,7 @@ fun MetadataEventDetail(
profile?.nip05?.let {
Row(
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(4.dp)
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.relatedGap)
) {
Icon(
Icons.Default.Bolt,
@@ -139,7 +140,7 @@ fun MetadataEventDetail(
LazyColumn(
modifier = Modifier.fillMaxSize(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(10.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125)
) {
item {
Column(
@@ -148,8 +149,8 @@ fun MetadataEventDetail(
horizontalAlignment = Alignment.CenterHorizontally
) {
Row(
modifier = Modifier.fillMaxWidth().padding(20.dp),
horizontalArrangement = Arrangement.spacedBy(10.dp),
modifier = Modifier.fillMaxWidth().padding(MaterialTheme.spacing.space250),
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125),
verticalAlignment = Alignment.CenterVertically
) {
ProfileAvatar(
@@ -224,7 +225,7 @@ fun MetadataEventDetail(
}
Text(
modifier = Modifier.fillMaxWidth().padding(
horizontal = 20.dp
horizontal = MaterialTheme.spacing.space250
),
maxLines = 2,
overflow = TextOverflow.Ellipsis,
@@ -248,7 +249,7 @@ fun MetadataEventDetail(
)
Spacer(
modifier = Modifier.width(10.dp)
modifier = Modifier.width(MaterialTheme.spacing.space125)
)
Text("Add To Group")
@@ -269,7 +270,7 @@ fun MetadataEventDetail(
)
Spacer(
modifier = Modifier.width(10.dp)
modifier = Modifier.width(MaterialTheme.spacing.space125)
)
Text("Block User")
@@ -294,7 +295,7 @@ fun MetadataEventDetail(
)
Spacer(
modifier = Modifier.width(10.dp)
modifier = Modifier.width(MaterialTheme.spacing.space125)
)
Text("Send Message")
}
@@ -314,7 +315,7 @@ private fun MetadataEventEventDetailPreview() {
TorchTheme {
Surface(
modifier = Modifier.padding(20.dp)
modifier = Modifier.padding(MaterialTheme.spacing.space250)
) {
MetadataEventDetail(
activeUserPublicKey = "",
@@ -47,6 +47,7 @@ import androidx.lifecycle.viewmodel.compose.viewModel
import press.mantra.compose.extensions.toFormattedTimeAndDateString
import com.vitorpamplona.quartz.nip01Core.core.HexKey
import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent
import press.mantra.compose.ui.theme.spacing
@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
@Composable
@@ -93,8 +94,8 @@ fun TextNoteEventDetail(
FlexibleBottomAppBar(
containerColor = Color.Transparent,
contentPadding = PaddingValues(
start = 10.dp,
end = 10.dp
start = MaterialTheme.spacing.space125,
end = MaterialTheme.spacing.space125
),
scrollBehavior = scrollBehavior
) {
@@ -114,8 +115,8 @@ fun TextNoteEventDetail(
color = MaterialTheme.colorScheme.surfaceVariant
) {
Row(
modifier = Modifier.padding(10.dp).fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(10.dp),
modifier = Modifier.padding(MaterialTheme.spacing.space125).fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125),
) {
// TODO: Load user profile...
Icon(
@@ -199,8 +200,8 @@ fun TextNoteEventDetail(
horizontalAlignment = Alignment.CenterHorizontally
) {
Row(
modifier = Modifier.fillMaxWidth().padding(12.dp),
horizontalArrangement = Arrangement.spacedBy(4.dp),
modifier = Modifier.fillMaxWidth().padding(MaterialTheme.spacing.space150),
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.relatedGap),
verticalAlignment = Alignment.CenterVertically
) {
val profile = localNostrEvent.profile
@@ -254,7 +255,7 @@ fun TextNoteEventDetail(
press.mantra.compose.ui.composable.widgets.content.RichContent(
modifier = Modifier.fillMaxWidth().padding(
horizontal = 20.dp
horizontal = MaterialTheme.spacing.space250
),
nostrEvent = localNostrEvent.nostrEvent,
localQuotedNostrEvent = localNostrEvent.localQuotedNostrEvent,
@@ -263,7 +264,7 @@ fun TextNoteEventDetail(
)
Row(
modifier = Modifier.fillMaxWidth().padding(20.dp),
modifier = Modifier.fillMaxWidth().padding(MaterialTheme.spacing.space250),
horizontalArrangement = Arrangement.Start
) {
Text(
@@ -385,7 +386,7 @@ private fun TextNoteEventDetailPreview() {
press.mantra.compose.ui.theme.TorchTheme {
Surface(
modifier = Modifier.padding(20.dp)
modifier = Modifier.padding(MaterialTheme.spacing.space250)
) {
TextNoteEventDetail(
localNostrEvent = press.mantra.compose.database.model.intermdiate.LocalNostrEvent(
@@ -37,6 +37,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import press.mantra.compose.ui.theme.spacing
/** Provides a Material3 [ModalBottomSheet] with some presets. Content is contained in a [Column] with [internalPadding]. */
@OptIn(ExperimentalMaterial3Api::class)
@@ -52,7 +53,7 @@ fun ModalBottomSheet(
dragHandle: @Composable (() -> Unit)? = { BottomSheetDefaults. DragHandle() },
contentWindowInsets: @Composable () -> WindowInsets = { BottomSheetDefaults.windowInsets },
contentHeight: Dp = Dp.Unspecified,
internalPadding: PaddingValues = PaddingValues(top = 0.dp, start = 20.dp, end = 20.dp, bottom = 64.dp),
internalPadding: PaddingValues = PaddingValues(top = MaterialTheme.spacing.space0, start = MaterialTheme.spacing.space250, end = MaterialTheme.spacing.space250, bottom = MaterialTheme.spacing.space800),
isContentScrollable: Boolean = true,
dismissOnScrimClick: Boolean = true,
dismissOnBack: Boolean = true,
@@ -28,6 +28,7 @@ import androidx.compose.ui.unit.dp
import press.mantra.compose.ui.composable.navigation.routes.Route
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import press.mantra.compose.ui.theme.spacing
@OptIn(ExperimentalMaterial3Api::class)
@@ -49,8 +50,8 @@ fun NewChatBottomSheetDialog(
) {
// Sheet content
Column(
modifier = Modifier.fillMaxWidth().padding(10.dp),
verticalArrangement = Arrangement.spacedBy(4.dp),
modifier = Modifier.fillMaxWidth().padding(MaterialTheme.spacing.space125),
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.relatedGap),
horizontalAlignment = Alignment.CenterHorizontally
) {
Text(
@@ -126,7 +127,7 @@ fun NewChatBottomSheetDialog(
contentDescription = "Close new chat"
)
Spacer(
modifier = Modifier.width(10.dp)
modifier = Modifier.width(MaterialTheme.spacing.space125)
)
Text("Close")
}
@@ -42,6 +42,7 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey
import fr.acinq.phoenix.utils.Parser
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import press.mantra.compose.ui.theme.spacing
@Composable
fun StartDirectMessageToNpubOrNip05Dialog(
@@ -62,21 +63,21 @@ fun StartDirectMessageToNpubOrNip05Dialog(
modifier = Modifier
.fillMaxWidth()
.wrapContentHeight()
.padding(16.dp),
.padding(MaterialTheme.spacing.containerPadding),
shape = RoundedCornerShape(16.dp),
) {
val textFieldState = rememberTextFieldState()
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(10.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125)
) {
Spacer(
modifier = Modifier.height(4.dp)
modifier = Modifier.height(MaterialTheme.spacing.space50)
)
Text(
modifier = Modifier.fillMaxWidth().padding(
horizontal = 20.dp,
horizontal = MaterialTheme.spacing.space250,
),
text = "Start chat via npub or nip05",
style = MaterialTheme.typography.labelMedium,
@@ -155,7 +156,7 @@ fun StartDirectMessageToNpubOrNip05Dialog(
Text("Start Chat")
Spacer(
modifier = Modifier.width(10.dp)
modifier = Modifier.width(MaterialTheme.spacing.space125)
)
Icon(
@@ -23,6 +23,7 @@ import com.vitorpamplona.quartz.nip01Core.core.HexKey
import com.vitorpamplona.quartz.nip10Notes.TextNoteEvent
import com.vitorpamplona.quartz.nip18Reposts.RepostEvent
import kotlin.time.Instant
import press.mantra.compose.ui.theme.spacing
@Composable
fun press.mantra.compose.database.model.intermdiate.LocalNostrEvent.ListView(
@@ -33,13 +34,13 @@ fun press.mantra.compose.database.model.intermdiate.LocalNostrEvent.ListView(
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(10.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125)
) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(
horizontal = 10.dp
horizontal = MaterialTheme.spacing.space125
).clickable(
enabled = true,
onClick = {
@@ -47,7 +48,7 @@ fun press.mantra.compose.database.model.intermdiate.LocalNostrEvent.ListView(
}
),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(4.dp)
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.relatedGap)
) {
Icon(
modifier = Modifier.size(
@@ -123,7 +124,7 @@ fun press.mantra.compose.database.model.intermdiate.LocalNostrEvent.ListView(
private fun EventListViewRepostedPreview() {
press.mantra.compose.ui.theme.TorchTheme {
Surface(
modifier = Modifier.padding(20.dp)
modifier = Modifier.padding(MaterialTheme.spacing.space250)
) {
press.mantra.compose.database.model.intermdiate.LocalNostrEvent(
nostrEvent = press.mantra.compose.database.model.NostrEvent(
@@ -174,7 +175,7 @@ private fun EventListViewRepostedPreview() {
private fun EventListViewInReplyPreview() {
press.mantra.compose.ui.theme.TorchTheme {
Surface(
modifier = Modifier.padding(20.dp)
modifier = Modifier.padding(MaterialTheme.spacing.space250)
) {
press.mantra.compose.database.model.intermdiate.LocalNostrEvent(
nostrEvent = press.mantra.compose.database.model.NostrEvent(
@@ -24,6 +24,7 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import press.mantra.compose.extensions.toFormattedTimeAndDateString
import com.vitorpamplona.quartz.nip01Core.core.HexKey
import press.mantra.compose.ui.theme.spacing
@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable
@@ -42,7 +43,7 @@ internal fun TextNoteFeedItem(
if (localInReplyToNostrEvent != null) {
Row(
modifier = Modifier.fillMaxWidth().padding(
horizontal = 20.dp
horizontal = MaterialTheme.spacing.space250
),
horizontalArrangement = Arrangement.End,
verticalAlignment = Alignment.CenterVertically
@@ -67,15 +68,15 @@ internal fun TextNoteFeedItem(
ElevatedCard(
modifier = Modifier.padding(
horizontal = 10.dp
horizontal = MaterialTheme.spacing.space125
),
onClick = {
onNavigateToEvent.invoke(nostrEvent.id)
}
) {
Column(
modifier = Modifier.padding(10.dp).fillMaxWidth(),
verticalArrangement = Arrangement.spacedBy(10.dp),
modifier = Modifier.padding(MaterialTheme.spacing.space125).fillMaxWidth(),
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125),
horizontalAlignment = Alignment.CenterHorizontally
) {
if (profile != null) {
@@ -85,7 +86,7 @@ internal fun TextNoteFeedItem(
onNavigateToEvent.invoke(profile.nostrEventId)
}
),
horizontalArrangement = Arrangement.spacedBy(10.dp, Alignment.Start),
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125, Alignment.Start),
verticalAlignment = Alignment.CenterVertically
) {
press.mantra.compose.ui.composable.widgets.profile.ProfileAvatar(
@@ -128,7 +129,7 @@ internal fun TextNoteFeedItem(
LazyRow(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.spacedBy(
10.dp,
MaterialTheme.spacing.space125,
alignment = Alignment.Start
)
) {
@@ -181,7 +182,7 @@ internal fun TextNoteFeedItem(
private fun TextNoteFeedItemPreview() {
press.mantra.compose.ui.theme.TorchTheme {
Surface(
modifier = Modifier.padding(20.dp)
modifier = Modifier.padding(MaterialTheme.spacing.space250)
) {
TextNoteFeedItem(
nostrEvent = press.mantra.compose.database.model.NostrEvent(
@@ -212,7 +213,7 @@ private fun TextNoteFeedItemPreview() {
private fun TextNoteFeedItemInReplyToPreview() {
press.mantra.compose.ui.theme.TorchTheme {
Surface(
modifier = Modifier.padding(20.dp)
modifier = Modifier.padding(MaterialTheme.spacing.space250)
) {
TextNoteFeedItem(
nostrEvent = press.mantra.compose.database.model.NostrEvent(
@@ -266,7 +267,7 @@ private fun TextNoteFeedItemInReplyToPreview() {
private fun TextNoteFeedItemQuoteNostrEventPreview() {
press.mantra.compose.ui.theme.TorchTheme {
Surface(
modifier = Modifier.padding(20.dp)
modifier = Modifier.padding(MaterialTheme.spacing.space250)
) {
TextNoteFeedItem(
nostrEvent = press.mantra.compose.database.model.NostrEvent(
@@ -8,6 +8,7 @@ import androidx.compose.material.icons.filled.AccountCircle
import androidx.compose.material.icons.filled.Face5
import androidx.compose.material.icons.filled.FaceRetouchingOff
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Surface
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
@@ -20,6 +21,7 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import coil3.compose.AsyncImage
import press.mantra.compose.ui.theme.spacing
@Composable
fun ProfileAvatar(
@@ -93,7 +95,7 @@ fun ProfileAvatar(
fun ProfileAvatarPreview() {
press.mantra.compose.ui.theme.TorchTheme {
Surface(
modifier = Modifier.padding(20.dp)
modifier = Modifier.padding(MaterialTheme.spacing.space250)
) {
ProfileAvatar(
publicKey = "hwgwefwase",
@@ -46,6 +46,7 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import com.machankura.compose.ui.composable.widgets.buttons.Clickable
import press.mantra.compose.ui.composable.widgets.dialogs.ModalBottomSheet
import press.mantra.compose.ui.theme.spacing
object WalletAvatars {
val list = listOf(
@@ -61,7 +62,7 @@ object WalletAvatars {
}
@Composable
fun WalletAvatar(avatar: String, fontSize: TextUnit = 28.sp, borderColor: Color = Color.Transparent, backgroundColor: Color = MaterialTheme.colorScheme.surface, internalPadding: PaddingValues = PaddingValues(10.dp)) {
fun WalletAvatar(avatar: String, fontSize: TextUnit = 28.sp, borderColor: Color = Color.Transparent, backgroundColor: Color = MaterialTheme.colorScheme.surface, internalPadding: PaddingValues = PaddingValues(MaterialTheme.spacing.space125)) {
Box(modifier = Modifier.clip(CircleShape).background(backgroundColor).border(1.dp, color = borderColor, shape = CircleShape).padding(internalPadding), contentAlignment = Alignment.Center) {
Text(
text = avatar,
@@ -79,20 +80,20 @@ fun ColumnScope.AvatarPicker(
var showPickerDialog by remember { mutableStateOf(false) }
Clickable(onClick = { showPickerDialog = true }, modifier = Modifier.align(Alignment.CenterHorizontally)) {
WalletAvatar(avatar, fontSize = 48.sp, internalPadding = PaddingValues(16.dp))
WalletAvatar(avatar, fontSize = 48.sp, internalPadding = PaddingValues(MaterialTheme.spacing.containerPadding))
}
if (showPickerDialog) {
ModalBottomSheet(
onDismiss = { showPickerDialog = false },
horizontalAlignment = Alignment.CenterHorizontally,
internalPadding = PaddingValues(horizontal = 24.dp, vertical = 0.dp),
internalPadding = PaddingValues(horizontal = MaterialTheme.spacing.space300, vertical = MaterialTheme.spacing.space0),
isContentScrollable = false,
) {
// val s = stringResource(Res.string.wallet_edit_pick_avatar)
val s = "Edit avatar"
Text(s, style = MaterialTheme.typography.bodyMedium)
Spacer(modifier = Modifier.height(24.dp))
Spacer(modifier = Modifier.height(MaterialTheme.spacing.space300))
LazyVerticalGrid(
columns = GridCells.Fixed(6),
modifier = Modifier.fillMaxWidth()
@@ -49,6 +49,7 @@ import fr.acinq.phoenix.data.WalletId
import fr.acinq.phoenix.utils.preferences.GlobalPrefs
import fr.acinq.phoenix.utils.preferences.UserWalletMetadata
import fr.acinq.phoenix.utils.preferences.getByWalletIdOrDefault
import press.mantra.compose.ui.theme.spacing
@Composable
fun WalletsSelector(
@@ -82,9 +83,9 @@ fun WalletsSelector(
canEdit = canEdit,
onClick = { onWalletClick(currentWallet) }
)
Spacer(Modifier.height(12.dp))
Spacer(Modifier.height(MaterialTheme.spacing.space150))
HorizontalDivider()
Spacer(Modifier.height(8.dp))
Spacer(Modifier.height(MaterialTheme.spacing.space100))
}
}
items(items = otherWalletsList) { (walletId, userWallet) ->
@@ -96,7 +97,7 @@ fun WalletsSelector(
canEdit = canEdit,
onClick = { onWalletClick(userWallet) }
)
Spacer(Modifier.height(8.dp))
Spacer(Modifier.height(MaterialTheme.spacing.space100))
}
bottomContent?.let {
item { it.invoke() }
@@ -142,22 +143,22 @@ private fun AvailableWalletView(
Row(modifier = Modifier.height(IntrinsicSize.Min), verticalAlignment = Alignment.CenterVertically) {
Row(
modifier = Modifier
.padding(horizontal = 12.dp, vertical = 12.dp)
.padding(horizontal = MaterialTheme.spacing.space150, vertical = MaterialTheme.spacing.space150)
.weight(1f),
verticalAlignment = Alignment.CenterVertically
) {
WalletAvatar(avatar = metadata.avatar, backgroundColor = Color.Transparent, internalPadding = PaddingValues(4.dp))
Spacer(Modifier.width(12.dp))
WalletAvatar(avatar = metadata.avatar, backgroundColor = Color.Transparent, internalPadding = PaddingValues(MaterialTheme.spacing.space50))
Spacer(Modifier.width(MaterialTheme.spacing.space150))
Column {
Text(text = metadata.nameOrDefault(), modifier = Modifier, maxLines = 1, overflow = TextOverflow.Ellipsis, style = MaterialTheme.typography.bodyMedium)
Spacer(Modifier.height(2.dp))
Spacer(Modifier.height(MaterialTheme.spacing.space25))
Text(text = userWallet.nodeId, modifier = Modifier, maxLines = 1, overflow = TextOverflow.Ellipsis, style = MaterialTheme.typography.displayMedium.copy(fontFamily = FontFamily.Monospace, fontSize = 12.sp))
}
}
if (isCurrent && canEdit) {
Spacer(Modifier.width(8.dp))
Spacer(Modifier.width(MaterialTheme.spacing.space100))
// TODO: PhoenixIcon(R.drawable.ic_edit, tint = MaterialTheme.colorScheme.primary)
Spacer(Modifier.width(16.dp))
Spacer(Modifier.width(MaterialTheme.spacing.space200))
}
}
}
@@ -409,21 +409,21 @@ class ChatMessageListViewModel(
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(10.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125)
) {
if (chatRoomDetailMessageListUIState.chatMessageList.isEmpty()) {
Spacer(
modifier = Modifier.height(20.dp)
modifier = Modifier.height(MaterialTheme.spacing.space250)
)
Text(
modifier = Modifier.padding(20.dp),
modifier = Modifier.padding(MaterialTheme.spacing.space250),
text = "Currently no messages have been shared.\nBreak the ice.",
textAlign = TextAlign.Center
)
Spacer(
modifier = Modifier.height(20.dp)
modifier = Modifier.height(MaterialTheme.spacing.space250)
)
} else {
@@ -447,7 +447,7 @@ class ChatMessageListViewModel(
LazyColumn(
modifier = Modifier.fillMaxWidth().padding(MaterialTheme.spacing.space50),
verticalArrangement = Arrangement.spacedBy(10.dp),
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125),
reverseLayout = true
) {
// First item, and the layout is reversed, so this
@@ -479,7 +479,7 @@ class ChatMessageListViewModel(
) {
Row(
modifier = Modifier.fillMaxWidth().padding(8.dp),
modifier = Modifier.fillMaxWidth().padding(MaterialTheme.spacing.compactPadding),
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically
) {
@@ -620,13 +620,13 @@ class ChatMessageListViewModel(
},
) {
Column(
modifier = Modifier.padding(10.dp),
modifier = Modifier.padding(MaterialTheme.spacing.space125),
horizontalAlignment = if (localChatMessage.chatMessage.isUserMessage) {
Alignment.End
} else {
Alignment.Start
},
verticalArrangement = Arrangement.spacedBy(6.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space75)
) {
if (localChatMessage.chatMessage.isUserMessage.not()) {
Text(
@@ -645,7 +645,7 @@ class ChatMessageListViewModel(
// assume was the whole room.
if (localChatMessage.chatMessage.messageType == ChatMessage.TYPE_DIRECT_MESSAGE) {
Row(
horizontalArrangement = Arrangement.spacedBy(4.dp),
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.relatedGap),
verticalAlignment = Alignment.CenterVertically
) {
Icon(
@@ -677,7 +677,7 @@ class ChatMessageListViewModel(
Row(
horizontalArrangement = Arrangement.spacedBy(
10.dp,
MaterialTheme.spacing.space125,
Alignment.End
),
verticalAlignment = Alignment.CenterVertically,
@@ -858,8 +858,8 @@ private fun ProposalsAwaitingYouNotice(
)
) {
Row(
modifier = Modifier.fillMaxWidth().padding(12.dp),
horizontalArrangement = Arrangement.spacedBy(10.dp),
modifier = Modifier.fillMaxWidth().padding(MaterialTheme.spacing.space150),
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125),
verticalAlignment = Alignment.CenterVertically
) {
Icon(
@@ -869,7 +869,7 @@ private fun ProposalsAwaitingYouNotice(
Column(
modifier = Modifier.weight(1f),
verticalArrangement = Arrangement.spacedBy(2.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space25)
) {
Text(
text = if (single != null) {
@@ -924,8 +924,8 @@ private fun PrivateMessageNotice(
Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 20.dp, vertical = 10.dp),
horizontalArrangement = Arrangement.spacedBy(8.dp),
.padding(horizontal = MaterialTheme.spacing.space250, vertical = MaterialTheme.spacing.space125),
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.itemGap),
verticalAlignment = Alignment.CenterVertically
) {
Icon(
@@ -1030,8 +1030,8 @@ private fun RitualNotice(
modifier = Modifier
.fillMaxWidth()
.clickable(onClick = onClick)
.padding(horizontal = 20.dp, vertical = 10.dp),
horizontalArrangement = Arrangement.spacedBy(10.dp),
.padding(horizontal = MaterialTheme.spacing.space250, vertical = MaterialTheme.spacing.space125),
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125),
verticalAlignment = Alignment.CenterVertically
) {
Icon(
@@ -1042,7 +1042,7 @@ private fun RitualNotice(
Column(
modifier = Modifier.weight(1f),
verticalArrangement = Arrangement.spacedBy(2.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space25)
) {
Text(
text = buildAnnotatedString {
@@ -162,7 +162,7 @@ class ChatRoomListViewModel(
Column(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(10.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125)
) {
if (chatRoomListUIState.chatRoomList.isEmpty()) {
@@ -172,7 +172,7 @@ class ChatRoomListViewModel(
} else {
LazyColumn(
modifier = Modifier.fillMaxWidth(),
verticalArrangement = Arrangement.spacedBy(10.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125)
) {
items(
items = chatRoomListUIState.chatRoomList,
@@ -191,8 +191,8 @@ class ChatRoomListViewModel(
}
) {
Row(
modifier = Modifier.fillMaxWidth().padding(20.dp),
horizontalArrangement = Arrangement.spacedBy(10.dp),
modifier = Modifier.fillMaxWidth().padding(MaterialTheme.spacing.space250),
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125),
verticalAlignment = Alignment.CenterVertically
) {
// Both lines are clipped to one, so the name
@@ -201,7 +201,7 @@ class ChatRoomListViewModel(
// the clock off the row.
Column(
modifier = Modifier.weight(1f),
verticalArrangement = Arrangement.spacedBy(4.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.relatedGap)
) {
localChatRoom.RenderChatRoomTitleText()
localChatRoom.RenderChatRoomLastMessageText()
@@ -142,7 +142,7 @@ class FeedListViewModel(
LazyColumn(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(10.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125)
) {
items(
items = feedListUIState.localNostrEvents,
@@ -136,7 +136,7 @@ class FollowersListViewModel(
LazyColumn(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(10.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125)
) {
items(
items = followersListUIState.followers,
@@ -135,7 +135,7 @@ class FollowingListViewModel(
LazyColumn(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(10.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125)
) {
items(
items = feedListUIState.following,
@@ -146,7 +146,7 @@ class InReplyToViewModel(
LazyColumn(
modifier = Modifier.fillMaxWidth(),
horizontalAlignment = Alignment.CenterHorizontally,
verticalArrangement = Arrangement.spacedBy(10.dp)
verticalArrangement = Arrangement.spacedBy(MaterialTheme.spacing.space125)
) {
items(
items = feedListUIState.localNostrEvents,
+1 -1
View File
@@ -25,7 +25,7 @@ THEME="$UI/theme"
# Budgets. "-1" means not yet budgeted -- reported, but never fails --check.
# ---------------------------------------------------------------------------
BUDGET_HARDCODED_COLOR=9 # phase 3 drives to 0 outside theme/
BUDGET_SPACING_LITERALS=353 # phase 2 drives to 0
BUDGET_SPACING_LITERALS=0 # phase 2: reached 2026-09-08
BUDGET_BARE_CLICKABLE=33 # phase 3 drives to 0
BUDGET_NULL_DESCRIPTION=18 # phase 3 triages each one
BUDGET_STRING_LITERALS=-1 # phase 4 drives to <10
+20 -10
View File
@@ -20,11 +20,15 @@ is a dimension and is left alone.
import re, sys, io, os
UI = 'composeApp/src/commonMain/kotlin/press/mantra/compose/ui'
MAPPING = {} # filled by the caller
# {"padding": {"8": "compactPadding"}, "gap": {...}, "spacer": {...}, "*": {...}}
# A shape-specific entry wins over "*". Shape matters because the same number means
# different things in different positions: 8dp of padding is compactPadding, 8dp of gap
# is itemGap, and 8dp under a Spacer is neither.
MAPPING = {}
DRY = '--apply' not in sys.argv
def token(value):
return MAPPING.get(value)
def token(value, shape):
return MAPPING.get(shape, {}).get(value) or MAPPING.get('*', {}).get(value)
def spacer_spans(text):
"""Character ranges covered by a Spacer( ... ) call, brace-matched."""
@@ -92,18 +96,24 @@ def process(path):
edit = None
for m in re.finditer(r'\b(\d+)\.dp\b', text):
lit = m.group(0)
tok = token(m.group(1))
if tok is None:
continue
pos = m.start()
line_start = text.rfind('\n', 0, pos) + 1
line = text[line_start:text.find('\n', pos)]
if re.match(r'\s*(//|\*|/\*)', line): # a comment
continue
if in_spans(pos, pads) or in_spans(pos, gaps) or \
any(a <= pos < b for a, b, _ in hw):
edit = (m.start(), m.end(), tok, lit, line.strip()[:80])
break
if in_spans(pos, pads):
shape = 'padding'
elif in_spans(pos, gaps):
shape = 'gap'
elif any(a <= pos < b for a, b, _ in hw):
shape = 'spacer'
else:
continue
tok = token(m.group(1), shape)
if tok is None:
continue
edit = (m.start(), m.end(), tok, lit, line.strip()[:80])
break
if edit is None:
break
a, b, tok, lit, ctx = edit
+16
View File
@@ -61,6 +61,22 @@ def classify(path):
line = text[line_start:text.find('\n', pos)]
if re.match(r'\s*(//|\*|/\*)', line):
continue
# An explicit, reasoned opt-out. A value that is genuinely not a step in the
# spacing rhythm -- room reserved below a list, say -- is marked at the site
# rather than exempted by value in this file, so the reason travels with it
# and a reviewer sees it in the diff.
# Walk back over the unbroken run of comment lines directly above.
exempt = False
prev = text[:line_start].rstrip('\n').split('\n')
for candidate in reversed(prev[-8:]):
stripped = candidate.strip()
if not stripped.startswith('//'):
break
if 'm3-spacing-exempt' in stripped:
exempt = True
break
if exempt:
continue
entry = (path, text[:pos].count('\n') + 1, m.group(0), line.strip()[:90])
if inside(pos, pads) or inside(pos, gaps) or any(a <= pos < b for a, b in hw):
spacing.append(entry)