From c0df0048bdd0abeaaa7b17eb1f2d2b106032e724 Mon Sep 17 00:00:00 2001 From: Claude Date: Wed, 17 Jun 2026 12:29:51 +0000 Subject: [PATCH] feat: render workout notes through the kind-1 text pipeline MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Replace the plain-text note with TranslatableRichTextViewer (inside SensitivityWarning), the same renderer kind-1 notes use — so workout notes get links, mentions, hashtags, embeds, image/URL previews and inline translations. WorkoutDisplay now receives backgroundColor, canPreview, quotesLeft, accountViewModel and nav; both call sites (NoteCompose, ThreadFeedView) pass them through. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_015qgqQKHSewRHVM8vSCLt9P --- .../amethyst/ui/note/NoteCompose.kt | 2 +- .../loggedIn/threadview/ThreadFeedView.kt | 2 +- .../loggedIn/workouts/WorkoutDisplay.kt | 39 ++++++++++++++++--- 3 files changed, 35 insertions(+), 8 deletions(-) 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 70aff34cba..e41f4ae5e9 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 @@ -1379,7 +1379,7 @@ private fun RenderNoteRow( } is WorkoutRecordEvent -> { - WorkoutDisplay(baseNote) + WorkoutDisplay(baseNote, backgroundColor, canPreview, quotesLeft, accountViewModel, nav) } is BaseVoiceEvent -> { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/threadview/ThreadFeedView.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/threadview/ThreadFeedView.kt index 6174025d61..55cd5886a1 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/threadview/ThreadFeedView.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/threadview/ThreadFeedView.kt @@ -667,7 +667,7 @@ private fun FullBleedNoteCompose( } else if (noteEvent is PictureEvent) { PictureDisplay(baseNote, roundedCorner = true, ContentScale.FillWidth, PaddingValues(vertical = Size5dp), backgroundColor, accountViewModel = accountViewModel, nav) } else if (noteEvent is WorkoutRecordEvent) { - WorkoutDisplay(baseNote) + WorkoutDisplay(baseNote, backgroundColor, canPreview = true, quotesLeft = 3, accountViewModel = accountViewModel, nav = nav) } else if (noteEvent is BaseVoiceEvent) { VoiceHeader(noteEvent, baseNote, accountViewModel, nav) } else if (noteEvent is FileHeaderEvent) { diff --git a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/workouts/WorkoutDisplay.kt b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/workouts/WorkoutDisplay.kt index 48cdcd416b..e8a9cda509 100644 --- a/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/workouts/WorkoutDisplay.kt +++ b/amethyst/src/main/java/com/vitorpamplona/amethyst/ui/screen/loggedIn/workouts/WorkoutDisplay.kt @@ -36,17 +36,24 @@ import androidx.compose.material3.MaterialTheme import androidx.compose.material3.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.Immutable +import androidx.compose.runtime.MutableState import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.draw.clip +import androidx.compose.ui.graphics.Color import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.unit.dp import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.commons.icons.symbols.Icon import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbol import com.vitorpamplona.amethyst.commons.icons.symbols.MaterialSymbols +import com.vitorpamplona.amethyst.commons.model.toImmutableListOfLists import com.vitorpamplona.amethyst.model.Note +import com.vitorpamplona.amethyst.ui.components.SensitivityWarning +import com.vitorpamplona.amethyst.ui.components.TranslatableRichTextViewer +import com.vitorpamplona.amethyst.ui.navigation.navs.INav +import com.vitorpamplona.amethyst.ui.screen.loggedIn.AccountViewModel import com.vitorpamplona.amethyst.ui.stringRes import com.vitorpamplona.amethyst.ui.theme.placeholderText import com.vitorpamplona.quartz.experimental.fitness.workout.WorkoutRecordEvent @@ -213,7 +220,14 @@ private class Stat( ) @Composable -fun WorkoutDisplay(baseNote: Note) { +fun WorkoutDisplay( + baseNote: Note, + backgroundColor: MutableState, + canPreview: Boolean, + quotesLeft: Int, + accountViewModel: AccountViewModel, + nav: INav, +) { val event = (baseNote.event as? WorkoutRecordEvent) ?: return val miles = remember { phonePrefersMiles() } @@ -304,13 +318,26 @@ fun WorkoutDisplay(baseNote: Note) { WorkoutStatsGrid(secondaryStats) + // Route the note (event content) through the same kind-1 pipeline: rich text with + // links/mentions/hashtags, embeds, sensitivity warning and inline translations. val notes = event.content.trim() if (notes.isNotEmpty()) { - Text( - text = notes, - style = MaterialTheme.typography.bodyMedium, - modifier = Modifier.padding(top = 12.dp), - ) + val callbackUri = remember(baseNote) { baseNote.toNostrUri() } + val tags = remember(baseNote) { event.tags.toImmutableListOfLists() } + SensitivityWarning(note = baseNote, accountViewModel = accountViewModel) { + TranslatableRichTextViewer( + content = notes, + canPreview = canPreview, + quotesLeft = quotesLeft, + modifier = Modifier.fillMaxWidth().padding(top = 12.dp), + tags = tags, + backgroundColor = backgroundColor, + id = baseNote.idHex, + callbackUri = callbackUri, + accountViewModel = accountViewModel, + nav = nav, + ) + } } } }