From 1d385cae0f01c131cbb5befc7fc3d64c82214446 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 13 Jul 2026 16:04:36 +0000 Subject: [PATCH] refactor(ui): move HeaderPill and QuietMark to commons/ui/note The two note-header marker primitives are pure Compose with no Android dependencies, so they belong in the shared layer where the desktop app (and future iOS) can render the same design system. QuietMark's gray comes from a new commons ColorScheme.placeholderText extension (onSurface at 42%, matching the Android theme's value). The thin app-side wrappers (BoostedMark, DisplayPoW, DisplayDraft, DisplayOts, DisplayLocation, DisplayReward, ...) stay in amethyst: they bind the primitives to Android string resources (with existing translations that commons' compose-resources catalog does not have) and to app state (LocalCache loaders, AccountViewModel, navigation). Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01AgEpNtwnetPhETXQSdq4b5 --- .../vitorpamplona/amethyst/ui/note/NoteCompose.kt | 4 ++-- .../amethyst/ui/note/elements/BoostedMark.kt | 1 + .../amethyst/ui/note/elements/DisplayEditStatus.kt | 1 + .../amethyst/ui/note/elements/DisplayLocation.kt | 1 + .../amethyst/ui/note/elements/DisplayOts.kt | 1 + .../amethyst/ui/note/elements/DisplayPoW.kt | 1 + .../amethyst/ui/note/elements/DisplayReward.kt | 1 + .../ui/note/elements/NoteHeaderMarkersPreview.kt | 3 ++- .../loggedIn/chats/rooms/ChatroomHeaderCompose.kt | 2 +- .../amethyst/commons/ui/note}/HeaderPill.kt | 2 +- .../amethyst/commons/ui/note}/QuietMark.kt | 12 +++++++----- .../amethyst/commons/ui/theme/ThemeExtensions.kt | 8 ++++++++ 12 files changed, 27 insertions(+), 10 deletions(-) rename {amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements => commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/note}/HeaderPill.kt (98%) rename {amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements => commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/note}/QuietMark.kt (91%) diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt index 39ef85a00c..579844d990 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/NoteCompose.kt @@ -60,6 +60,8 @@ import com.vitorpamplona.amethyst.commons.icons.symbols.Icon import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols import com.vitorpamplona.amethyst.commons.model.nip28PublicChats.PublicChatChannel import com.vitorpamplona.amethyst.commons.ui.components.GenericLoadable +import com.vitorpamplona.amethyst.commons.ui.note.HeaderPill +import com.vitorpamplona.amethyst.commons.ui.note.QuietMark import com.vitorpamplona.amethyst.commons.ui.state.produceCachedStateAsync import com.vitorpamplona.amethyst.model.AddressableNote import com.vitorpamplona.amethyst.model.LocalCache @@ -84,9 +86,7 @@ import com.vitorpamplona.amethyst.ui.note.elements.DisplayLocation import com.vitorpamplona.amethyst.ui.note.elements.DisplayOts import com.vitorpamplona.amethyst.ui.note.elements.DisplayPoW import com.vitorpamplona.amethyst.ui.note.elements.DisplayReward -import com.vitorpamplona.amethyst.ui.note.elements.HeaderPill import com.vitorpamplona.amethyst.ui.note.elements.MoreOptionsButton -import com.vitorpamplona.amethyst.ui.note.elements.QuietMark import com.vitorpamplona.amethyst.ui.note.elements.Reward import com.vitorpamplona.amethyst.ui.note.elements.ShowForkInformation import com.vitorpamplona.amethyst.ui.note.elements.StaleRelayHint diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/BoostedMark.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/BoostedMark.kt index 7b81088adc..c48531aaca 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/BoostedMark.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/BoostedMark.kt @@ -22,6 +22,7 @@ package com.vitorpamplona.amethyst.ui.note.elements import androidx.compose.runtime.Composable import com.vitorpamplona.amethyst.R +import com.vitorpamplona.amethyst.commons.ui.note.QuietMark import com.vitorpamplona.amethyst.ui.stringRes @Composable diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayEditStatus.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayEditStatus.kt index 48a2e6b60f..0ffae65a1d 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayEditStatus.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayEditStatus.kt @@ -22,6 +22,7 @@ package com.vitorpamplona.amethyst.ui.note.elements import androidx.compose.runtime.Composable import com.vitorpamplona.amethyst.R +import com.vitorpamplona.amethyst.commons.ui.note.QuietMark import com.vitorpamplona.amethyst.ui.note.types.EditState import com.vitorpamplona.amethyst.ui.stringRes diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayLocation.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayLocation.kt index cf240cb7f2..a32e65d1b5 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayLocation.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayLocation.kt @@ -22,6 +22,7 @@ package com.vitorpamplona.amethyst.ui.note.elements import androidx.compose.runtime.Composable import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols +import com.vitorpamplona.amethyst.commons.ui.note.HeaderPill import com.vitorpamplona.amethyst.ui.navigation.navs.INav import com.vitorpamplona.amethyst.ui.navigation.routes.Route import com.vitorpamplona.amethyst.ui.note.creators.location.LoadCityName diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayOts.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayOts.kt index c5cf453138..319293d69c 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayOts.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayOts.kt @@ -27,6 +27,7 @@ import androidx.compose.runtime.remember import androidx.compose.ui.platform.LocalContext import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols +import com.vitorpamplona.amethyst.commons.ui.note.HeaderPill import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.ui.note.LoadOts import com.vitorpamplona.amethyst.ui.note.timeAgoNoDot diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayPoW.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayPoW.kt index 64aad9648a..e6fc7b772e 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayPoW.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayPoW.kt @@ -24,6 +24,7 @@ import androidx.compose.runtime.Composable import androidx.compose.ui.tooling.preview.Preview import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols +import com.vitorpamplona.amethyst.commons.ui.note.HeaderPill import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.theme.ThemeComparisonColumn diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayReward.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayReward.kt index 0b36780bd1..fbd4270e07 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayReward.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/DisplayReward.kt @@ -55,6 +55,7 @@ import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewmodel.compose.viewModel import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols +import com.vitorpamplona.amethyst.commons.ui.note.HeaderPill import com.vitorpamplona.amethyst.model.Account import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.service.relayClient.reqCommand.event.observeNoteReplies diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/NoteHeaderMarkersPreview.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/NoteHeaderMarkersPreview.kt index ea1c4287df..02438cf59a 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/NoteHeaderMarkersPreview.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/NoteHeaderMarkersPreview.kt @@ -76,7 +76,8 @@ private val COMMUNITY_ADDRESS = "34550:" + "c".repeat(64) + ":amethyst-users" * Design-system preview for the note-header first row, rendered by the REAL * `FirstUserInfoRow` over notes seeded into [LocalCache] — the same pattern * the ZapPollNote/Poll previews use. Rows go from bare to fully loaded so the - * two marker tiers ([HeaderPill] and [QuietMark]) can be reviewed together. + * two marker tiers (`HeaderPill` and `QuietMark`, now in `commons/ui/note`) + * can be reviewed together. * * Two markers cannot appear in a static preview because their visibility is * computed inside effects that previews never run: the followed-hashtag label diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/rooms/ChatroomHeaderCompose.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/rooms/ChatroomHeaderCompose.kt index 976cbe3032..52aec3f3c0 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/rooms/ChatroomHeaderCompose.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/chats/rooms/ChatroomHeaderCompose.kt @@ -52,6 +52,7 @@ import com.vitorpamplona.amethyst.commons.model.emphChat.EphemeralChatChannel import com.vitorpamplona.amethyst.commons.model.marmotGroups.MarmotGroupChatroom import com.vitorpamplona.amethyst.commons.model.nip28PublicChats.PublicChatChannel import com.vitorpamplona.amethyst.commons.model.nip29RelayGroups.RelayGroupChannel +import com.vitorpamplona.amethyst.commons.ui.note.HeaderPill import com.vitorpamplona.amethyst.model.LocalCache import com.vitorpamplona.amethyst.model.Note import com.vitorpamplona.amethyst.model.User @@ -72,7 +73,6 @@ import com.vitorpamplona.amethyst.ui.note.LoadDecryptedContentOrNull import com.vitorpamplona.amethyst.ui.note.LoadPublicChatChannel import com.vitorpamplona.amethyst.ui.note.NonClickableUserPictures import com.vitorpamplona.amethyst.ui.note.ObserveDraftEvent -import com.vitorpamplona.amethyst.ui.note.elements.HeaderPill import com.vitorpamplona.amethyst.ui.note.elements.TimeAgoStyle import com.vitorpamplona.amethyst.ui.note.elements.ToggleableTimeAgoText import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/HeaderPill.kt b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/note/HeaderPill.kt similarity index 98% rename from amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/HeaderPill.kt rename to commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/note/HeaderPill.kt index 6661391c8b..6c4dc4726b 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/HeaderPill.kt +++ b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/note/HeaderPill.kt @@ -18,7 +18,7 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.amethyst.ui.note.elements +package com.vitorpamplona.amethyst.commons.ui.note import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/QuietMark.kt b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/note/QuietMark.kt similarity index 91% rename from amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/QuietMark.kt rename to commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/note/QuietMark.kt index acd339471e..8f3cea79a7 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/note/elements/QuietMark.kt +++ b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/note/QuietMark.kt @@ -18,7 +18,7 @@ * AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ -package com.vitorpamplona.amethyst.ui.note.elements +package com.vitorpamplona.amethyst.commons.ui.note import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement @@ -31,10 +31,12 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp import com.vitorpamplona.amethyst.commons.icons.symbols.Icon import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbol -import com.vitorpamplona.amethyst.ui.theme.Font12SP -import com.vitorpamplona.amethyst.ui.theme.placeholderText +import com.vitorpamplona.amethyst.commons.ui.theme.placeholderText + +private val QuietMarkFontSize = 12.sp /** * Quiet passive-state marker for note headers: Boosted, Draft, Edited, pinned, @@ -70,8 +72,8 @@ fun QuietMark( Text( text = text, color = MaterialTheme.colorScheme.placeholderText, - fontSize = Font12SP, - lineHeight = Font12SP, + fontSize = QuietMarkFontSize, + lineHeight = QuietMarkFontSize, fontWeight = FontWeight.Medium, maxLines = 1, ) diff --git a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/theme/ThemeExtensions.kt b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/theme/ThemeExtensions.kt index 0e8e0866fd..ad4488e405 100644 --- a/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/theme/ThemeExtensions.kt +++ b/commons/src/commonMain/kotlin/com/vitorpamplona/amethyst/commons/ui/theme/ThemeExtensions.kt @@ -21,6 +21,7 @@ package com.vitorpamplona.amethyst.commons.ui.theme import androidx.compose.material3.ColorScheme +import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.ColorFilter import androidx.compose.ui.graphics.luminance @@ -36,3 +37,10 @@ val ColorScheme.isLight: Boolean */ val ColorScheme.onBackgroundColorFilter: ColorFilter get() = ColorFilter.tint(onBackground) + +/** + * De-emphasized text/icon color for secondary markers and hints. Matches the + * Android app's placeholderText, which is the palette's onSurface at 42%. + */ +val ColorScheme.placeholderText: Color + get() = onSurface.copy(alpha = 0.42f)